From a52a50d4d1c72a31f12d286940ea8d4d5cddbdfe Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 4 Apr 2024 18:29:09 +0200 Subject: [PATCH] Persist theme Persist theme in sqlite database. A new table was created for this. Add migration to add table for persisted theme --- lib/database.dart | 26 ++-- lib/database.g.dart | 214 ++++++++++++++++++++++++++++----- lib/main.dart | 20 +-- lib/notes_app.dart | 34 +++--- lib/persisted_brightness.dart | 40 ++++++ lib/persistence_bloc.dart | 79 ------------ lib/persistent_notes_bloc.dart | 78 ++++++++++++ lib/theme_bloc.dart | 75 +++++++++--- pubspec.lock | 2 +- pubspec.yaml | 1 + 10 files changed, 411 insertions(+), 158 deletions(-) create mode 100644 lib/persisted_brightness.dart delete mode 100644 lib/persistence_bloc.dart create mode 100644 lib/persistent_notes_bloc.dart diff --git a/lib/database.dart b/lib/database.dart index a48c48a..ec880aa 100644 --- a/lib/database.dart +++ b/lib/database.dart @@ -8,17 +8,23 @@ import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart'; part 'database.g.dart'; -class NoteTable extends Table { +var database = AppDatabase(); //global, since we should only use one instance + +class PersistentNote extends Table { TextColumn get id => text()(); TextColumn get content => text()(); } -@DriftDatabase(tables: [NoteTable]) +class PersistentTheme extends Table { + TextColumn get brightness => text().withDefault(const Constant("dark"))(); +} + +@DriftDatabase(tables: [PersistentNote, PersistentTheme]) class AppDatabase extends _$AppDatabase { AppDatabase() : super(_openConnection()); @override - int get schemaVersion => 1; + int get schemaVersion => 2; @override MigrationStrategy get migration { @@ -27,30 +33,26 @@ class AppDatabase extends _$AppDatabase { await m.createAll(); }, onUpgrade: (Migrator m, int from, int to) async { - if (from < 2) {} + if (from < 2) { + await m.renameTable(persistentNote, "note_table"); + await m.createTable(persistentTheme); + } }, ); } } LazyDatabase _openConnection() { - // the LazyDatabase util lets us find the right location for the file async. return LazyDatabase(() async { - // put the database file, called db.sqlite here, into the documents folder - // for your app. final dbFolder = await getApplicationDocumentsDirectory(); final file = File(p.join(dbFolder.path, 'db.sqlite')); - // Also work around limitations on old Android versions if (Platform.isAndroid) { await applyWorkaroundToOpenSqlite3OnOldAndroidVersions(); } - // Make sqlite3 pick a more suitable location for temporary files - the - // one from the system may be inaccessible due to sandboxing. final cachebase = (await getTemporaryDirectory()).path; - // We can't access /tmp on Android, which sqlite3 would try by default. - // Explicitly tell it about the correct temporary directory. + sqlite3.tempDirectory = cachebase; return NativeDatabase.createInBackground(file); diff --git a/lib/database.g.dart b/lib/database.g.dart index eb1e489..a072e0d 100644 --- a/lib/database.g.dart +++ b/lib/database.g.dart @@ -3,12 +3,12 @@ part of 'database.dart'; // ignore_for_file: type=lint -class $NoteTableTable extends NoteTable - with TableInfo<$NoteTableTable, NoteTableData> { +class $PersistentNoteTable extends PersistentNote + with TableInfo<$PersistentNoteTable, PersistentNoteData> { @override final GeneratedDatabase attachedDatabase; final String? _alias; - $NoteTableTable(this.attachedDatabase, [this._alias]); + $PersistentNoteTable(this.attachedDatabase, [this._alias]); static const VerificationMeta _idMeta = const VerificationMeta('id'); @override late final GeneratedColumn id = GeneratedColumn( @@ -26,9 +26,9 @@ class $NoteTableTable extends NoteTable String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'note_table'; + static const String $name = 'persistent_note'; @override - VerificationContext validateIntegrity(Insertable instance, + VerificationContext validateIntegrity(Insertable instance, {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); @@ -49,9 +49,9 @@ class $NoteTableTable extends NoteTable @override Set get $primaryKey => const {}; @override - NoteTableData map(Map data, {String? tablePrefix}) { + PersistentNoteData map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return NoteTableData( + return PersistentNoteData( id: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}id'])!, content: attachedDatabase.typeMapping @@ -60,15 +60,16 @@ class $NoteTableTable extends NoteTable } @override - $NoteTableTable createAlias(String alias) { - return $NoteTableTable(attachedDatabase, alias); + $PersistentNoteTable createAlias(String alias) { + return $PersistentNoteTable(attachedDatabase, alias); } } -class NoteTableData extends DataClass implements Insertable { +class PersistentNoteData extends DataClass + implements Insertable { final String id; final String content; - const NoteTableData({required this.id, required this.content}); + const PersistentNoteData({required this.id, required this.content}); @override Map toColumns(bool nullToAbsent) { final map = {}; @@ -77,17 +78,17 @@ class NoteTableData extends DataClass implements Insertable { return map; } - NoteTableCompanion toCompanion(bool nullToAbsent) { - return NoteTableCompanion( + PersistentNoteCompanion toCompanion(bool nullToAbsent) { + return PersistentNoteCompanion( id: Value(id), content: Value(content), ); } - factory NoteTableData.fromJson(Map json, + factory PersistentNoteData.fromJson(Map json, {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; - return NoteTableData( + return PersistentNoteData( id: serializer.fromJson(json['id']), content: serializer.fromJson(json['content']), ); @@ -101,13 +102,14 @@ class NoteTableData extends DataClass implements Insertable { }; } - NoteTableData copyWith({String? id, String? content}) => NoteTableData( + PersistentNoteData copyWith({String? id, String? content}) => + PersistentNoteData( id: id ?? this.id, content: content ?? this.content, ); @override String toString() { - return (StringBuffer('NoteTableData(') + return (StringBuffer('PersistentNoteData(') ..write('id: $id, ') ..write('content: $content') ..write(')')) @@ -119,27 +121,27 @@ class NoteTableData extends DataClass implements Insertable { @override bool operator ==(Object other) => identical(this, other) || - (other is NoteTableData && + (other is PersistentNoteData && other.id == this.id && other.content == this.content); } -class NoteTableCompanion extends UpdateCompanion { +class PersistentNoteCompanion extends UpdateCompanion { final Value id; final Value content; final Value rowid; - const NoteTableCompanion({ + const PersistentNoteCompanion({ this.id = const Value.absent(), this.content = const Value.absent(), this.rowid = const Value.absent(), }); - NoteTableCompanion.insert({ + PersistentNoteCompanion.insert({ required String id, required String content, this.rowid = const Value.absent(), }) : id = Value(id), content = Value(content); - static Insertable custom({ + static Insertable custom({ Expression? id, Expression? content, Expression? rowid, @@ -151,9 +153,9 @@ class NoteTableCompanion extends UpdateCompanion { }); } - NoteTableCompanion copyWith( + PersistentNoteCompanion copyWith( {Value? id, Value? content, Value? rowid}) { - return NoteTableCompanion( + return PersistentNoteCompanion( id: id ?? this.id, content: content ?? this.content, rowid: rowid ?? this.rowid, @@ -177,7 +179,7 @@ class NoteTableCompanion extends UpdateCompanion { @override String toString() { - return (StringBuffer('NoteTableCompanion(') + return (StringBuffer('PersistentNoteCompanion(') ..write('id: $id, ') ..write('content: $content, ') ..write('rowid: $rowid') @@ -186,12 +188,170 @@ class NoteTableCompanion extends UpdateCompanion { } } +class $PersistentThemeTable extends PersistentTheme + with TableInfo<$PersistentThemeTable, PersistentThemeData> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $PersistentThemeTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _brightnessMeta = + const VerificationMeta('brightness'); + @override + late final GeneratedColumn brightness = GeneratedColumn( + 'brightness', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultValue: const Constant("dark")); + @override + List get $columns => [brightness]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'persistent_theme'; + @override + VerificationContext validateIntegrity( + Insertable instance, + {bool isInserting = false}) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('brightness')) { + context.handle( + _brightnessMeta, + brightness.isAcceptableOrUnknown( + data['brightness']!, _brightnessMeta)); + } + return context; + } + + @override + Set get $primaryKey => const {}; + @override + PersistentThemeData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PersistentThemeData( + brightness: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}brightness'])!, + ); + } + + @override + $PersistentThemeTable createAlias(String alias) { + return $PersistentThemeTable(attachedDatabase, alias); + } +} + +class PersistentThemeData extends DataClass + implements Insertable { + final String brightness; + const PersistentThemeData({required this.brightness}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['brightness'] = Variable(brightness); + return map; + } + + PersistentThemeCompanion toCompanion(bool nullToAbsent) { + return PersistentThemeCompanion( + brightness: Value(brightness), + ); + } + + factory PersistentThemeData.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PersistentThemeData( + brightness: serializer.fromJson(json['brightness']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'brightness': serializer.toJson(brightness), + }; + } + + PersistentThemeData copyWith({String? brightness}) => PersistentThemeData( + brightness: brightness ?? this.brightness, + ); + @override + String toString() { + return (StringBuffer('PersistentThemeData(') + ..write('brightness: $brightness') + ..write(')')) + .toString(); + } + + @override + int get hashCode => brightness.hashCode; + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PersistentThemeData && other.brightness == this.brightness); +} + +class PersistentThemeCompanion extends UpdateCompanion { + final Value brightness; + final Value rowid; + const PersistentThemeCompanion({ + this.brightness = const Value.absent(), + this.rowid = const Value.absent(), + }); + PersistentThemeCompanion.insert({ + this.brightness = const Value.absent(), + this.rowid = const Value.absent(), + }); + static Insertable custom({ + Expression? brightness, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (brightness != null) 'brightness': brightness, + if (rowid != null) 'rowid': rowid, + }); + } + + PersistentThemeCompanion copyWith( + {Value? brightness, Value? rowid}) { + return PersistentThemeCompanion( + brightness: brightness ?? this.brightness, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (brightness.present) { + map['brightness'] = Variable(brightness.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PersistentThemeCompanion(') + ..write('brightness: $brightness, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + abstract class _$AppDatabase extends GeneratedDatabase { _$AppDatabase(QueryExecutor e) : super(e); - late final $NoteTableTable noteTable = $NoteTableTable(this); + late final $PersistentNoteTable persistentNote = $PersistentNoteTable(this); + late final $PersistentThemeTable persistentTheme = + $PersistentThemeTable(this); @override Iterable> get allTables => allSchemaEntities.whereType>(); @override - List get allSchemaEntities => [noteTable]; + List get allSchemaEntities => + [persistentNote, persistentTheme]; } diff --git a/lib/main.dart b/lib/main.dart index c862b68..51e5380 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,25 +1,31 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:fnotes/notes_app.dart'; -import 'package:fnotes/persistence_bloc.dart'; +import 'package:fnotes/persisted_brightness.dart'; +import 'package:fnotes/persistent_notes_bloc.dart'; import 'package:fnotes/theme_bloc.dart'; -void main() { +void main() async { WidgetsFlutterBinding.ensureInitialized(); //for drift - runApp(const MainApp()); + + PersistedBrightness persistedBrightness = + await PersistedThemeBloc.getPersistedBrightness(); + + runApp(MainApp(brightness: persistedBrightness.toFlutterBrightness())); } class MainApp extends StatelessWidget { - const MainApp({super.key}); + final Brightness brightness; + const MainApp({super.key, required this.brightness}); @override Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider(create: (context) => ThemeBloc()), - BlocProvider(create: (context) => PersistenceBloc()) + BlocProvider(create: (context) => PersistedThemeBloc(brightness)), + BlocProvider(create: (context) => PersistentNotesBloc()), ], - child: BlocBuilder( + child: BlocBuilder( builder: (context, state) { return MaterialApp( theme: state.theme, diff --git a/lib/notes_app.dart b/lib/notes_app.dart index b12b3c4..b432557 100644 --- a/lib/notes_app.dart +++ b/lib/notes_app.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:fnotes/note.dart'; -import 'package:fnotes/persistence_bloc.dart'; +import 'package:fnotes/persistent_notes_bloc.dart'; import 'package:fnotes/theme_bloc.dart'; class NotesApp extends StatefulWidget { @@ -18,7 +18,7 @@ class _NotesAppState extends State { @override void initState() { - context.read().add(LoadNotesEvent()); + context.read().add(LoadNotesEvent()); super.initState(); } @@ -31,29 +31,29 @@ class _NotesAppState extends State { IconButton( icon: const Icon(Icons.light_mode), onPressed: () { - context.read().add(ThemeEvent()); + context.read().add(ThemeChangedEvent()); }, ) ], ), - body: BlocBuilder( - builder: (context, state) { - return BlocBuilder( - builder: (context, blocState) { + body: BlocBuilder( + builder: (context, themeState) { + return BlocBuilder( + builder: (context, notesState) { return ListView.builder( - itemCount: blocState.notes.length, + itemCount: notesState.notes.length, itemBuilder: (context, index) { return Dismissible( onDismissed: (direction) { - context.read().add(NoteDismissed( + context.read().add(NoteDismissed( Note.withId( - id: blocState.notes[index].id, - content: blocState.notes[index].content))); + id: notesState.notes[index].id, + content: notesState.notes[index].content))); }, - key: ValueKey(blocState.notes[index]), + key: ValueKey(notesState.notes[index]), child: Card( elevation: 5, - color: state.theme.colorScheme.primaryContainer, + color: themeState.theme.colorScheme.primaryContainer, child: SizedBox( height: 50, child: Padding( @@ -61,10 +61,10 @@ class _NotesAppState extends State { child: Align( alignment: Alignment.centerLeft, child: Text( - blocState.notes[index].content, + notesState.notes[index].content, style: TextStyle( - color: - state.theme.colorScheme.onPrimaryContainer), + color: themeState + .theme.colorScheme.onPrimaryContainer), ), ), ), @@ -83,7 +83,7 @@ class _NotesAppState extends State { (value) { if (value != null && value.isNotEmpty) { context - .read() + .read() .add(NoteEntered(Note(content: value))); } }, diff --git a/lib/persisted_brightness.dart b/lib/persisted_brightness.dart new file mode 100644 index 0000000..84f7df4 --- /dev/null +++ b/lib/persisted_brightness.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +class PersistedBrightness { + final String brightness; + + PersistedBrightness(this.brightness); + + factory PersistedBrightness.fromFlutterBrightness(Brightness brightness) { + var persistedBrightness = "light"; + + if (brightness == Brightness.dark) { + persistedBrightness = "dark"; + } + + return PersistedBrightness(persistedBrightness); + } + + Brightness toFlutterBrightness() { + Brightness flutterBrightness = Brightness.light; + + if (brightness == "dark") { + flutterBrightness = Brightness.dark; + } + + return flutterBrightness; + } + + @override + String toString() => brightness; + + PersistedBrightness toOpposite() { + var newBrightness = "light"; + + if (brightness == "light") { + newBrightness = "dark"; + } + + return PersistedBrightness(newBrightness); + } +} diff --git a/lib/persistence_bloc.dart b/lib/persistence_bloc.dart deleted file mode 100644 index 3171843..0000000 --- a/lib/persistence_bloc.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:fnotes/database.dart'; -import 'package:fnotes/note.dart'; - -class PersistenceBloc extends Bloc { - static final database = AppDatabase(); - - PersistenceBloc() : super(PersistenceState.init()) { - on(storeAllNotes); - on(loadAllNotes); - on(storeNote); - on(deleteNote); - } - - void storeAllNotes(PersistenceEvent event, Emitter emit) {} - - void loadAllNotes( - PersistenceEvent event, Emitter emit) async { - List list = []; - - await database.select(database.noteTable).get().then( - (value) { - list = value.map((row) { - return Note.withId(id: row.id, content: row.content); - }).toList(); - }, - ); - - emit(PersistenceState(notes: list)); - } - - void storeNote(NoteEntered event, Emitter emit) async { - await database.into(database.noteTable).insert(NoteTableCompanion.insert( - id: event.note.id, - content: event.note.content, - )); - - var newNotes = state.notes; - newNotes.add(Note.withId(id: event.note.id, content: event.note.content)); - emit(PersistenceState(notes: newNotes)); - } - - void deleteNote(NoteDismissed event, Emitter emit) { - (database.delete(database.noteTable) - ..where((tbl) => tbl.id.equals(event.note.id))) - .go(); - - var newNotes = - state.notes.where((note) => note.id != event.note.id).toList(); - - emit(PersistenceState(notes: newNotes)); - } -} - -class PersistenceEvent {} - -class LoadNotesEvent extends PersistenceEvent {} - -class StoreNotesEvent extends PersistenceEvent {} - -class NoteEntered extends PersistenceEvent { - final Note note; - NoteEntered(this.note); -} - -class NoteDismissed extends PersistenceEvent { - final Note note; - NoteDismissed(this.note); -} - -class PersistenceState { - List notes = List.empty(growable: true); - - PersistenceState({required this.notes}); - - factory PersistenceState.init() { - return PersistenceState(notes: []); - } -} diff --git a/lib/persistent_notes_bloc.dart b/lib/persistent_notes_bloc.dart new file mode 100644 index 0000000..f7b4464 --- /dev/null +++ b/lib/persistent_notes_bloc.dart @@ -0,0 +1,78 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:fnotes/database.dart'; +import 'package:fnotes/note.dart'; + +class PersistentNotesBloc + extends Bloc { + PersistentNotesBloc() : super(PersistentNotesState.init()) { + on(loadAllNotes); + on(storeNote); + on(deleteNote); + } + + void storeAllNotes( + PersistentNotesEvent event, Emitter emit) {} + + void loadAllNotes( + PersistentNotesEvent event, Emitter emit) async { + List list = []; + + await database.select(database.persistentNote).get().then( + (value) { + list = value.map((row) { + return Note.withId(id: row.id, content: row.content); + }).toList(); + }, + ); + + emit(PersistentNotesState(notes: list)); + } + + void storeNote(NoteEntered event, Emitter emit) async { + await database + .into(database.persistentNote) + .insert(PersistentNoteCompanion.insert( + id: event.note.id, + content: event.note.content, + )); + + var newNotes = state.notes; + newNotes.add(Note.withId(id: event.note.id, content: event.note.content)); + emit(PersistentNotesState(notes: newNotes)); + } + + void deleteNote(NoteDismissed event, Emitter emit) { + (database.delete(database.persistentNote) + ..where((tbl) => tbl.id.equals(event.note.id))) + .go(); + + var newNotes = + state.notes.where((note) => note.id != event.note.id).toList(); + + emit(PersistentNotesState(notes: newNotes)); + } +} + +class PersistentNotesEvent {} + +class LoadNotesEvent extends PersistentNotesEvent {} + +class NoteEntered extends PersistentNotesEvent { + final Note note; + NoteEntered(this.note); +} + +class NoteDismissed extends PersistentNotesEvent { + final Note note; + NoteDismissed(this.note); +} + +class PersistentNotesState { + List notes = List.empty(growable: true); + + PersistentNotesState({required this.notes}); + + factory PersistentNotesState.init() { + return PersistentNotesState(notes: []); + } +} diff --git a/lib/theme_bloc.dart b/lib/theme_bloc.dart index 534c1e3..60f1aa5 100644 --- a/lib/theme_bloc.dart +++ b/lib/theme_bloc.dart @@ -1,33 +1,78 @@ +import 'package:drift/drift.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:fnotes/database.dart'; +import 'package:fnotes/persisted_brightness.dart'; -class ThemeBloc extends Bloc { - ThemeBloc() : super(ThemeState.init()) { - on(switchTheme); +class PersistedThemeBloc extends Bloc { + PersistedThemeBloc(Brightness brightness) + : super(ThemeState.withBrightness(brightness)) { + on(switchTheme); + on(loadTheme); } - void switchTheme(ThemeEvent event, Emitter emit) { - if (state.theme.brightness == Brightness.light) { - emit(ThemeState.withBrightness(Brightness.dark)); - } else { - emit(ThemeState.withBrightness(Brightness.light)); - } + void switchTheme(ThemeChangedEvent event, Emitter emit) async { + await database.delete(database.persistentTheme).go(); + + var newBrightness = + PersistedBrightness.fromFlutterBrightness(state.theme.brightness) + .toOpposite(); + + await database + .into(database.persistentTheme) + .insert(PersistentThemeCompanion.insert( + brightness: Value(newBrightness.toString()), + )); + + emit(ThemeState.withBrightness(newBrightness.toFlutterBrightness())); + } + + void loadTheme(LoadThemeEvent event, Emitter emit) async { + PersistedBrightness persistedBrightness = await getPersistedBrightness(); + emit(ThemeState.withBrightness(persistedBrightness.toFlutterBrightness())); + } + + static Future getPersistedBrightness() async { + PersistedBrightness persistedBrightness = PersistedBrightness("light"); + + await database.select(database.persistentTheme).get().then( + (value) { + var brightnessIter = value.map((row) { + return row.brightness; + }); + + if (brightnessIter.isNotEmpty) { + persistedBrightness = PersistedBrightness(brightnessIter.first); + } + }, + ); + return persistedBrightness; } } class ThemeEvent {} +class LoadThemeEvent extends ThemeEvent {} + +class ThemeChangedEvent extends ThemeEvent {} + class ThemeState { final ThemeData theme; - static final ThemeData initTheme = ThemeData( - colorScheme: ColorScheme.fromSeed( - seedColor: Colors.lightBlue, brightness: Brightness.light), - ); ThemeState({required this.theme}); - factory ThemeState.init() { - return ThemeState(theme: initTheme); + static Future fetchAndConstructInitState() async { + PersistedBrightness persistedBrightness = PersistedBrightness('light'); + await database.select(database.persistentTheme).get().then( + (value) { + var brightnessIter = value.map((row) { + return row.brightness; + }); + persistedBrightness = PersistedBrightness(brightnessIter.first); + }, + ); + + return ThemeState.withBrightness(persistedBrightness.toFlutterBrightness()); } factory ThemeState.withBrightness(Brightness brightness) { diff --git a/pubspec.lock b/pubspec.lock index 831f385..4241fa3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -513,7 +513,7 @@ packages: source: hosted version: "1.5.1" provider: - dependency: transitive + dependency: "direct main" description: name: provider sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c diff --git a/pubspec.yaml b/pubspec.yaml index b52d3a0..0ace492 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: sqlite3_flutter_libs: ^0.5.20 uuid: ^4.3.3 sqlite3: ^2.4.0 + provider: ^6.1.2 dev_dependencies: flutter_test: