Persist theme
Persist theme in sqlite database. A new table was created for this. Add migration to add table for persisted theme
This commit is contained in:
parent
66d7d27a81
commit
a52a50d4d1
@ -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);
|
||||
|
@ -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<String> id = GeneratedColumn<String>(
|
||||
@ -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<NoteTableData> instance,
|
||||
VerificationContext validateIntegrity(Insertable<PersistentNoteData> instance,
|
||||
{bool isInserting = false}) {
|
||||
final context = VerificationContext();
|
||||
final data = instance.toColumns(true);
|
||||
@ -49,9 +49,9 @@ class $NoteTableTable extends NoteTable
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => const {};
|
||||
@override
|
||||
NoteTableData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
PersistentNoteData map(Map<String, dynamic> 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<NoteTableData> {
|
||||
class PersistentNoteData extends DataClass
|
||||
implements Insertable<PersistentNoteData> {
|
||||
final String id;
|
||||
final String content;
|
||||
const NoteTableData({required this.id, required this.content});
|
||||
const PersistentNoteData({required this.id, required this.content});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
@ -77,17 +78,17 @@ class NoteTableData extends DataClass implements Insertable<NoteTableData> {
|
||||
return map;
|
||||
}
|
||||
|
||||
NoteTableCompanion toCompanion(bool nullToAbsent) {
|
||||
return NoteTableCompanion(
|
||||
PersistentNoteCompanion toCompanion(bool nullToAbsent) {
|
||||
return PersistentNoteCompanion(
|
||||
id: Value(id),
|
||||
content: Value(content),
|
||||
);
|
||||
}
|
||||
|
||||
factory NoteTableData.fromJson(Map<String, dynamic> json,
|
||||
factory PersistentNoteData.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return NoteTableData(
|
||||
return PersistentNoteData(
|
||||
id: serializer.fromJson<String>(json['id']),
|
||||
content: serializer.fromJson<String>(json['content']),
|
||||
);
|
||||
@ -101,13 +102,14 @@ class NoteTableData extends DataClass implements Insertable<NoteTableData> {
|
||||
};
|
||||
}
|
||||
|
||||
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<NoteTableData> {
|
||||
@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<NoteTableData> {
|
||||
class PersistentNoteCompanion extends UpdateCompanion<PersistentNoteData> {
|
||||
final Value<String> id;
|
||||
final Value<String> content;
|
||||
final Value<int> 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<NoteTableData> custom({
|
||||
static Insertable<PersistentNoteData> custom({
|
||||
Expression<String>? id,
|
||||
Expression<String>? content,
|
||||
Expression<int>? rowid,
|
||||
@ -151,9 +153,9 @@ class NoteTableCompanion extends UpdateCompanion<NoteTableData> {
|
||||
});
|
||||
}
|
||||
|
||||
NoteTableCompanion copyWith(
|
||||
PersistentNoteCompanion copyWith(
|
||||
{Value<String>? id, Value<String>? content, Value<int>? 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<NoteTableData> {
|
||||
|
||||
@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<NoteTableData> {
|
||||
}
|
||||
}
|
||||
|
||||
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<String> brightness = GeneratedColumn<String>(
|
||||
'brightness', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
defaultValue: const Constant("dark"));
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [brightness];
|
||||
@override
|
||||
String get aliasedName => _alias ?? actualTableName;
|
||||
@override
|
||||
String get actualTableName => $name;
|
||||
static const String $name = 'persistent_theme';
|
||||
@override
|
||||
VerificationContext validateIntegrity(
|
||||
Insertable<PersistentThemeData> 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<GeneratedColumn> get $primaryKey => const {};
|
||||
@override
|
||||
PersistentThemeData map(Map<String, dynamic> 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<PersistentThemeData> {
|
||||
final String brightness;
|
||||
const PersistentThemeData({required this.brightness});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['brightness'] = Variable<String>(brightness);
|
||||
return map;
|
||||
}
|
||||
|
||||
PersistentThemeCompanion toCompanion(bool nullToAbsent) {
|
||||
return PersistentThemeCompanion(
|
||||
brightness: Value(brightness),
|
||||
);
|
||||
}
|
||||
|
||||
factory PersistentThemeData.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return PersistentThemeData(
|
||||
brightness: serializer.fromJson<String>(json['brightness']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'brightness': serializer.toJson<String>(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<PersistentThemeData> {
|
||||
final Value<String> brightness;
|
||||
final Value<int> 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<PersistentThemeData> custom({
|
||||
Expression<String>? brightness,
|
||||
Expression<int>? rowid,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (brightness != null) 'brightness': brightness,
|
||||
if (rowid != null) 'rowid': rowid,
|
||||
});
|
||||
}
|
||||
|
||||
PersistentThemeCompanion copyWith(
|
||||
{Value<String>? brightness, Value<int>? rowid}) {
|
||||
return PersistentThemeCompanion(
|
||||
brightness: brightness ?? this.brightness,
|
||||
rowid: rowid ?? this.rowid,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (brightness.present) {
|
||||
map['brightness'] = Variable<String>(brightness.value);
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(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<TableInfo<Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [noteTable];
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[persistentNote, persistentTheme];
|
||||
}
|
||||
|
@ -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<ThemeBloc, ThemeState>(
|
||||
child: BlocBuilder<PersistedThemeBloc, ThemeState>(
|
||||
builder: (context, state) {
|
||||
return MaterialApp(
|
||||
theme: state.theme,
|
||||
|
@ -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<NotesApp> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
context.read<PersistenceBloc>().add(LoadNotesEvent());
|
||||
context.read<PersistentNotesBloc>().add(LoadNotesEvent());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@ -31,29 +31,29 @@ class _NotesAppState extends State<NotesApp> {
|
||||
IconButton(
|
||||
icon: const Icon(Icons.light_mode),
|
||||
onPressed: () {
|
||||
context.read<ThemeBloc>().add(ThemeEvent());
|
||||
context.read<PersistedThemeBloc>().add(ThemeChangedEvent());
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
body: BlocBuilder<ThemeBloc, ThemeState>(
|
||||
builder: (context, state) {
|
||||
return BlocBuilder<PersistenceBloc, PersistenceState>(
|
||||
builder: (context, blocState) {
|
||||
body: BlocBuilder<PersistedThemeBloc, ThemeState>(
|
||||
builder: (context, themeState) {
|
||||
return BlocBuilder<PersistentNotesBloc, PersistentNotesState>(
|
||||
builder: (context, notesState) {
|
||||
return ListView.builder(
|
||||
itemCount: blocState.notes.length,
|
||||
itemCount: notesState.notes.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Dismissible(
|
||||
onDismissed: (direction) {
|
||||
context.read<PersistenceBloc>().add(NoteDismissed(
|
||||
context.read<PersistentNotesBloc>().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<NotesApp> {
|
||||
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<NotesApp> {
|
||||
(value) {
|
||||
if (value != null && value.isNotEmpty) {
|
||||
context
|
||||
.read<PersistenceBloc>()
|
||||
.read<PersistentNotesBloc>()
|
||||
.add(NoteEntered(Note(content: value)));
|
||||
}
|
||||
},
|
||||
|
40
lib/persisted_brightness.dart
Normal file
40
lib/persisted_brightness.dart
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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<PersistenceEvent, PersistenceState> {
|
||||
static final database = AppDatabase();
|
||||
|
||||
PersistenceBloc() : super(PersistenceState.init()) {
|
||||
on<StoreNotesEvent>(storeAllNotes);
|
||||
on<LoadNotesEvent>(loadAllNotes);
|
||||
on<NoteEntered>(storeNote);
|
||||
on<NoteDismissed>(deleteNote);
|
||||
}
|
||||
|
||||
void storeAllNotes(PersistenceEvent event, Emitter<PersistenceState> emit) {}
|
||||
|
||||
void loadAllNotes(
|
||||
PersistenceEvent event, Emitter<PersistenceState> emit) async {
|
||||
List<Note> 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<PersistenceState> 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<PersistenceState> 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<Note> notes = List.empty(growable: true);
|
||||
|
||||
PersistenceState({required this.notes});
|
||||
|
||||
factory PersistenceState.init() {
|
||||
return PersistenceState(notes: []);
|
||||
}
|
||||
}
|
78
lib/persistent_notes_bloc.dart
Normal file
78
lib/persistent_notes_bloc.dart
Normal file
@ -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<PersistentNotesEvent, PersistentNotesState> {
|
||||
PersistentNotesBloc() : super(PersistentNotesState.init()) {
|
||||
on<LoadNotesEvent>(loadAllNotes);
|
||||
on<NoteEntered>(storeNote);
|
||||
on<NoteDismissed>(deleteNote);
|
||||
}
|
||||
|
||||
void storeAllNotes(
|
||||
PersistentNotesEvent event, Emitter<PersistentNotesState> emit) {}
|
||||
|
||||
void loadAllNotes(
|
||||
PersistentNotesEvent event, Emitter<PersistentNotesState> emit) async {
|
||||
List<Note> 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<PersistentNotesState> 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<PersistentNotesState> 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<Note> notes = List.empty(growable: true);
|
||||
|
||||
PersistentNotesState({required this.notes});
|
||||
|
||||
factory PersistentNotesState.init() {
|
||||
return PersistentNotesState(notes: []);
|
||||
}
|
||||
}
|
@ -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<ThemeEvent, ThemeState> {
|
||||
ThemeBloc() : super(ThemeState.init()) {
|
||||
on<ThemeEvent>(switchTheme);
|
||||
class PersistedThemeBloc extends Bloc<ThemeEvent, ThemeState> {
|
||||
PersistedThemeBloc(Brightness brightness)
|
||||
: super(ThemeState.withBrightness(brightness)) {
|
||||
on<ThemeChangedEvent>(switchTheme);
|
||||
on<LoadThemeEvent>(loadTheme);
|
||||
}
|
||||
|
||||
void switchTheme(ThemeEvent event, Emitter<ThemeState> emit) {
|
||||
if (state.theme.brightness == Brightness.light) {
|
||||
emit(ThemeState.withBrightness(Brightness.dark));
|
||||
} else {
|
||||
emit(ThemeState.withBrightness(Brightness.light));
|
||||
void switchTheme(ThemeChangedEvent event, Emitter<ThemeState> 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<ThemeState> emit) async {
|
||||
PersistedBrightness persistedBrightness = await getPersistedBrightness();
|
||||
emit(ThemeState.withBrightness(persistedBrightness.toFlutterBrightness()));
|
||||
}
|
||||
|
||||
static Future<PersistedBrightness> 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<ThemeState> 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) {
|
||||
|
@ -513,7 +513,7 @@ packages:
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
provider:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: provider
|
||||
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user