reload files view when adding/editing a note
organize in folders
This commit is contained in:
parent
7baef13eae
commit
ab1bacea00
95
lib/app.dart
Normal file
95
lib/app.dart
Normal file
@ -0,0 +1,95 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:notes/context/file_change_notifier.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'canvas/drawing_page.dart';
|
||||
import 'pages/all_notes_page.dart';
|
||||
import 'widgets/collapse_drawer.dart';
|
||||
|
||||
class App extends StatefulWidget {
|
||||
const App({super.key});
|
||||
|
||||
@override
|
||||
State<App> createState() => _AppState();
|
||||
}
|
||||
|
||||
class _AppState extends State<App> {
|
||||
View activePage = View.all;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (ctx) {
|
||||
final notifier = FileChangeNotifier();
|
||||
notifier.loadAllNotes();
|
||||
return notifier;
|
||||
},
|
||||
child: Scaffold(
|
||||
floatingActionButton: _fab(),
|
||||
body: Row(
|
||||
children: [
|
||||
CollapseDrawer(
|
||||
onPageChange: (View newPage) =>
|
||||
setState(() => activePage = newPage),
|
||||
activePage: activePage,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: const Color(0xff0d0d0d),
|
||||
child: _buildPage(),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _fab() {
|
||||
switch (activePage) {
|
||||
case View.all:
|
||||
case View.folders:
|
||||
return FloatingActionButton(
|
||||
onPressed: () async {
|
||||
final now = DateTime.now();
|
||||
String filename =
|
||||
'note-${now.year}_${now.month}_${now.day}-${now.hour}_${now.minute}.dbnote';
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (ctx) => DrawingPage(filePath: filename),
|
||||
),
|
||||
).then((value) =>
|
||||
Provider.of<FileChangeNotifier>(context, listen: false)
|
||||
.loadAllNotes());
|
||||
},
|
||||
backgroundColor: const Color(0xff3f3f3f),
|
||||
child: const Icon(Icons.edit_calendar_outlined, color: Colors.orange),
|
||||
);
|
||||
default:
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildPage() {
|
||||
switch (activePage) {
|
||||
case View.all:
|
||||
return const AllNotesPage();
|
||||
case View.shared:
|
||||
return const Text(
|
||||
'shared notebooks WIP',
|
||||
style: TextStyle(color: Colors.white),
|
||||
);
|
||||
case View.recycle:
|
||||
return const Text(
|
||||
'recycle bin WIP',
|
||||
style: TextStyle(color: Colors.white),
|
||||
);
|
||||
case View.folders:
|
||||
return const Text(
|
||||
'Folders WIP',
|
||||
style: TextStyle(color: Colors.white),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -8,8 +8,8 @@ import 'my_painter.dart';
|
||||
import 'paint_controller.dart';
|
||||
import 'screen_document_mapping.dart';
|
||||
|
||||
import '../icon_material_button.dart';
|
||||
import '../tool_bar.dart';
|
||||
import '../widgets/icon_material_button.dart';
|
||||
import '../widgets/tool_bar.dart';
|
||||
|
||||
/// Handles input events and draws canvas element
|
||||
class DrawingPage extends StatefulWidget {
|
||||
|
31
lib/context/file_change_notifier.dart
Normal file
31
lib/context/file_change_notifier.dart
Normal file
@ -0,0 +1,31 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
import '../savesystem/path.dart';
|
||||
import '../widgets/note_tile.dart';
|
||||
|
||||
class FileChangeNotifier extends ChangeNotifier {
|
||||
FileChangeNotifier();
|
||||
|
||||
List<NoteTileData> tiledata = [];
|
||||
|
||||
Future<List<NoteTileData>> loadAllNotes() async {
|
||||
final path = await getSavePath();
|
||||
final dta = await path
|
||||
.list()
|
||||
.where((fsentity) => fsentity.path.endsWith('.dbnote'))
|
||||
.asyncMap((fsentity) async {
|
||||
final lastmodified = (await fsentity.stat()).modified;
|
||||
final filename = fsentity.path.split(Platform.pathSeparator).last;
|
||||
final name = filename.substring(0, filename.length - 7);
|
||||
return NoteTileData(name, filename, lastmodified);
|
||||
}).toList();
|
||||
dta.sort(
|
||||
(a, b) => a.lastModified.isAfter(b.lastModified) ? -1 : 1,
|
||||
);
|
||||
notifyListeners();
|
||||
tiledata = dta;
|
||||
return dta;
|
||||
}
|
||||
}
|
105
lib/main.dart
105
lib/main.dart
@ -1,114 +1,15 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:notes/collapse_drawer.dart';
|
||||
import 'package:notes/all_notes_page.dart';
|
||||
import 'package:notes/canvas/drawing_page.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
|
||||
import 'app.dart';
|
||||
|
||||
void main() {
|
||||
if (defaultTargetPlatform != TargetPlatform.android &&
|
||||
defaultTargetPlatform != TargetPlatform.iOS) {
|
||||
sqfliteFfiInit();
|
||||
databaseFactory = databaseFactoryFfi;
|
||||
}
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
theme: ThemeData(
|
||||
// is not restarted.
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
home: const MyHomePage(title: 'Flutter Demo Home Page'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({super.key, required this.title});
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
View activePage = View.all;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
floatingActionButton: _fab(),
|
||||
body: Row(
|
||||
children: [
|
||||
CollapseDrawer(
|
||||
onPageChange: (View newPage) =>
|
||||
setState(() => activePage = newPage),
|
||||
activePage: activePage,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: const Color(0xff0d0d0d),
|
||||
child: _buildPage(),
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _fab() {
|
||||
switch (activePage) {
|
||||
case View.all:
|
||||
case View.folders:
|
||||
return FloatingActionButton(
|
||||
onPressed: () {
|
||||
final now = DateTime.now();
|
||||
String filename =
|
||||
'note-${now.year}_${now.month}_${now.day}-${now.hour}_${now.minute}.dbnote';
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DrawingPage(filePath: filename),
|
||||
),
|
||||
);
|
||||
},
|
||||
backgroundColor: const Color(0xff3f3f3f),
|
||||
child: const Icon(Icons.edit_calendar_outlined, color: Colors.orange),
|
||||
);
|
||||
default:
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildPage() {
|
||||
switch (activePage) {
|
||||
case View.all:
|
||||
return const AllNotesPage();
|
||||
case View.shared:
|
||||
return const Text(
|
||||
'shared notebooks WIP',
|
||||
style: TextStyle(color: Colors.white),
|
||||
);
|
||||
case View.recycle:
|
||||
return const Text(
|
||||
'recycle bin WIP',
|
||||
style: TextStyle(color: Colors.white),
|
||||
);
|
||||
case View.folders:
|
||||
return const Text(
|
||||
'Folders WIP',
|
||||
style: TextStyle(color: Colors.white),
|
||||
);
|
||||
}
|
||||
}
|
||||
runApp(const MaterialApp(home: App()));
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:notes/icon_material_button.dart';
|
||||
import 'package:notes/note_tile.dart';
|
||||
import 'package:notes/savesystem/path.dart';
|
||||
import 'package:notes/context/file_change_notifier.dart';
|
||||
import 'package:notes/widgets/icon_material_button.dart';
|
||||
import 'package:notes/widgets/note_tile.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class AllNotesPage extends StatefulWidget {
|
||||
const AllNotesPage({Key? key}) : super(key: key);
|
||||
@ -13,8 +12,6 @@ class AllNotesPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _AllNotesPageState extends State<AllNotesPage> {
|
||||
List<NoteTileData> tileData = [];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
@ -63,40 +60,19 @@ class _AllNotesPageState extends State<AllNotesPage> {
|
||||
|
||||
Widget _buildNoteTiles() {
|
||||
return Expanded(
|
||||
child: GridView.builder(
|
||||
child: Consumer<FileChangeNotifier>(
|
||||
builder: (BuildContext context, value, Widget? child) {
|
||||
return GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 5,
|
||||
),
|
||||
padding: const EdgeInsets.all(2),
|
||||
itemBuilder: (BuildContext context, int idx) =>
|
||||
NoteTile(data: tileData[idx]),
|
||||
itemCount: tileData.length,
|
||||
NoteTile(data: value.tiledata[idx]),
|
||||
itemCount: value.tiledata.length,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadAllNotes();
|
||||
}
|
||||
|
||||
Future<void> loadAllNotes() async {
|
||||
final path = await getSavePath();
|
||||
final dta = await path
|
||||
.list()
|
||||
.where((fsentity) => fsentity.path.endsWith('.dbnote'))
|
||||
.asyncMap((fsentity) async {
|
||||
final lastmodified = (await fsentity.stat()).modified;
|
||||
final filename = fsentity.path.split(Platform.pathSeparator).last;
|
||||
final name = filename.substring(0, filename.length - 7);
|
||||
return NoteTileData(name, filename, lastmodified);
|
||||
}).toList();
|
||||
dta.sort(
|
||||
(a, b) => a.lastModified.isAfter(b.lastModified) ? -1 : 1,
|
||||
);
|
||||
setState(() {
|
||||
tileData = dta;
|
||||
});
|
||||
}
|
||||
}
|
@ -2,13 +2,13 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
Future<Directory> getSavePath() async {
|
||||
Directory dbpath;
|
||||
if (defaultTargetPlatform == TargetPlatform.android ||
|
||||
defaultTargetPlatform == TargetPlatform.iOS) {
|
||||
dbpath = Directory(await getDatabasesPath());
|
||||
dbpath = Directory(
|
||||
'${(await getApplicationDocumentsDirectory()).path}${Platform.pathSeparator}notes');
|
||||
} else {
|
||||
dbpath = Directory(
|
||||
'${(await getApplicationDocumentsDirectory()).path}${Platform.pathSeparator}notes');
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:notes/drawer_item.dart';
|
||||
import 'package:notes/context/file_change_notifier.dart';
|
||||
import 'package:notes/widgets/drawer_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
enum View { all, shared, recycle, folders }
|
||||
|
||||
@ -98,12 +100,14 @@ class _CollapseDrawerState extends State<CollapseDrawer>
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
DrawerItem(
|
||||
Consumer<FileChangeNotifier>(
|
||||
builder: (context, value, child) => DrawerItem(
|
||||
dta: ItemData('All Notes', Icons.book),
|
||||
collapsed: collapsed,
|
||||
endText: '7',
|
||||
endText: value.tiledata.length.toString(),
|
||||
active: widget.activePage == View.all,
|
||||
onTap: () => widget.onPageChange(View.all)),
|
||||
),
|
||||
DrawerItem(
|
||||
dta: ItemData('Shared Notebooks', Icons.person_outline),
|
||||
collapsed: collapsed,
|
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'canvas/drawing_page.dart';
|
||||
import '../canvas/drawing_page.dart';
|
||||
import '../context/file_change_notifier.dart';
|
||||
|
||||
class NoteTileData {
|
||||
final String name;
|
||||
@ -24,7 +26,9 @@ class NoteTile extends StatelessWidget {
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DrawingPage(filePath: data.relativePath),
|
||||
),
|
||||
);
|
||||
).then((value) =>
|
||||
Provider.of<FileChangeNotifier>(context, listen: false)
|
||||
.loadAllNotes());
|
||||
},
|
||||
child: SizedBox(
|
||||
width: 100,
|
@ -5,7 +5,7 @@ import 'package:iconify_flutter/iconify_flutter.dart';
|
||||
import 'package:iconify_flutter/icons/emojione_monotone.dart';
|
||||
import 'package:iconify_flutter/icons/jam.dart';
|
||||
|
||||
import 'canvas/paint_controller.dart';
|
||||
import '../canvas/paint_controller.dart';
|
||||
import 'icon_material_button.dart';
|
||||
|
||||
class ToolBar extends StatefulWidget {
|
14
pubspec.lock
14
pubspec.lock
@ -144,6 +144,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nested
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -242,6 +249,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.4"
|
||||
provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.4"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -35,6 +35,7 @@ dependencies:
|
||||
sqflite: ^2.2.0+2
|
||||
sqflite_common_ffi: ^2.2.0+1
|
||||
path_provider: ^2.0.11
|
||||
provider: ^6.0.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Loading…
Reference in New Issue
Block a user