mirror of
https://github.com/Nioux/AideDeJeu.git
synced 2025-10-30 15:06:06 +00:00
Réorg + menu
This commit is contained in:
parent
e91e7e4a39
commit
9bb7055832
9 changed files with 358 additions and 309 deletions
|
|
@ -5,6 +5,8 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
|
||||||
|
import 'models/filters.dart';
|
||||||
|
|
||||||
Database _database;
|
Database _database;
|
||||||
|
|
||||||
Future<Database> get database async {
|
Future<Database> get database async {
|
||||||
|
|
@ -59,7 +61,7 @@ Future<Item> loadChildrenItems(Item item, List<Filter> filters) async {
|
||||||
item.itemType.substring(0, item.itemType.length - 1);
|
item.itemType.substring(0, item.itemType.length - 1);
|
||||||
String family = "";
|
String family = "";
|
||||||
if (item is FilteredItems) {
|
if (item is FilteredItems) {
|
||||||
family = (item as FilteredItems)?.family ?? "";
|
family = item.family ?? "";
|
||||||
}
|
}
|
||||||
String whereFilter = "";
|
String whereFilter = "";
|
||||||
if(filters != null) {
|
if(filters != null) {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class MyApp extends StatelessWidget {
|
||||||
bodyText2: TextStyle(fontSize: 16.0),
|
bodyText2: TextStyle(fontSize: 16.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
home: MyHomePage(id: 'index.md'),
|
home: HomePage(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
aidedejeu_flutter/lib/models/filters.dart
Normal file
18
aidedejeu_flutter/lib/models/filters.dart
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
enum FilterType {
|
||||||
|
Choices, Range
|
||||||
|
}
|
||||||
|
class Filter {
|
||||||
|
String name;
|
||||||
|
FilterType type;
|
||||||
|
List<String> values;
|
||||||
|
Set<String> selectedValues = Set<String>();
|
||||||
|
RangeValues rangeValues;
|
||||||
|
|
||||||
|
Filter({this.name, this.type, this.values}) {
|
||||||
|
rangeValues = RangeValues(0, values.length.toDouble() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:aidedejeu_flutter/models/filters.dart';
|
||||||
|
|
||||||
class Item {
|
class Item {
|
||||||
String id;
|
String id;
|
||||||
|
|
@ -17,9 +17,7 @@ class Item {
|
||||||
String itemType;
|
String itemType;
|
||||||
List<Item> children;
|
List<Item> children;
|
||||||
|
|
||||||
Item({this.id, this.name, this.alias, this.markdown, this.itemType});
|
Item(Map<String, dynamic> map) {
|
||||||
|
|
||||||
Item.fromMap(Map<String, dynamic> map) {
|
|
||||||
this.id = map["Id"];
|
this.id = map["Id"];
|
||||||
this.rootId = map["RootId"];
|
this.rootId = map["RootId"];
|
||||||
this.name = map["Name"];
|
this.name = map["Name"];
|
||||||
|
|
@ -28,24 +26,6 @@ class Item {
|
||||||
this.markdown = map["Markdown"];
|
this.markdown = map["Markdown"];
|
||||||
this.itemType = map["ItemType"];
|
this.itemType = map["ItemType"];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*factory Item.fromMap(Map<String, dynamic> json) => new Item(
|
|
||||||
Id: json["Id"],
|
|
||||||
Name: json["Name"],
|
|
||||||
Alias: json["AltName"],
|
|
||||||
Markdown: json["Markdown"],
|
|
||||||
Discriminator: json["Discriminator"],
|
|
||||||
);*/
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() => {
|
|
||||||
"Id": id,
|
|
||||||
"RootId": rootId,
|
|
||||||
"Name": name,
|
|
||||||
"AltName": alias,
|
|
||||||
"AltNameText": aliasText,
|
|
||||||
"Markdown": markdown,
|
|
||||||
"ItemType": itemType,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MonsterItem extends Item {
|
class MonsterItem extends Item {
|
||||||
|
|
@ -75,8 +55,8 @@ class MonsterItem extends Item {
|
||||||
String challenge;
|
String challenge;
|
||||||
int xp;
|
int xp;
|
||||||
|
|
||||||
MonsterItem.fromMap(Map<String, dynamic> map)
|
MonsterItem(Map<String, dynamic> map)
|
||||||
: super.fromMap(map) {
|
: super(map) {
|
||||||
this.family = map["Family"];
|
this.family = map["Family"];
|
||||||
this.type = map["Type"];
|
this.type = map["Type"];
|
||||||
this.size = map["Size"];
|
this.size = map["Size"];
|
||||||
|
|
@ -107,37 +87,22 @@ class MonsterItem extends Item {
|
||||||
|
|
||||||
class Items extends Item {
|
class Items extends Item {
|
||||||
|
|
||||||
Items.fromMap(Map<String, dynamic> map)
|
Items(Map<String, dynamic> map)
|
||||||
: super.fromMap(map) {
|
: super(map) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class FilteredItems extends Items {
|
abstract class FilteredItems extends Items {
|
||||||
String family;
|
String family;
|
||||||
|
|
||||||
FilteredItems.fromMap(Map<String, dynamic> map)
|
FilteredItems(Map<String, dynamic> map)
|
||||||
: super.fromMap(map) {
|
: super(map) {
|
||||||
this.family = map["Family"];
|
this.family = map["Family"];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Filter> toFilterList();
|
List<Filter> toFilterList();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum FilterType {
|
|
||||||
Choices, Range
|
|
||||||
}
|
|
||||||
class Filter {
|
|
||||||
String name;
|
|
||||||
FilterType type;
|
|
||||||
List<String> values;
|
|
||||||
Set<String> selectedValues = Set<String>();
|
|
||||||
RangeValues rangeValues;
|
|
||||||
|
|
||||||
Filter({this.name, this.type, this.values}) {
|
|
||||||
rangeValues = RangeValues(0, values.length.toDouble() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MonsterItems extends FilteredItems {
|
class MonsterItems extends FilteredItems {
|
||||||
Filter types;
|
Filter types;
|
||||||
Filter challenges;
|
Filter challenges;
|
||||||
|
|
@ -145,8 +110,8 @@ class MonsterItems extends FilteredItems {
|
||||||
Filter sources;
|
Filter sources;
|
||||||
Filter terrains;
|
Filter terrains;
|
||||||
|
|
||||||
MonsterItems.fromMap(Map<String, dynamic> map)
|
MonsterItems(Map<String, dynamic> map)
|
||||||
: super.fromMap(map) {
|
: super(map) {
|
||||||
this.types = Filter(name: "Type", type: FilterType.Choices, values: map["Types"].toString().split("|"));
|
this.types = Filter(name: "Type", type: FilterType.Choices, values: map["Types"].toString().split("|"));
|
||||||
this.challenges = Filter(name: "Challenge", type: FilterType.Range, values: map["Challenges"].toString().split("|"));
|
this.challenges = Filter(name: "Challenge", type: FilterType.Range, values: map["Challenges"].toString().split("|"));
|
||||||
this.sizes = Filter(name: "Size", type: FilterType.Range, values: map["Sizes"].toString().split("|"));;
|
this.sizes = Filter(name: "Size", type: FilterType.Range, values: map["Sizes"].toString().split("|"));;
|
||||||
|
|
@ -154,8 +119,6 @@ class MonsterItems extends FilteredItems {
|
||||||
this.terrains = Filter(name: "Terrain", type: FilterType.Choices, values: map["Terrains"].toString().split("|"));
|
this.terrains = Filter(name: "Terrain", type: FilterType.Choices, values: map["Terrains"].toString().split("|"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map<String, dynamic> toMap() => {
|
|
||||||
//"Id": Id,
|
|
||||||
List<Filter> toFilterList() => {
|
List<Filter> toFilterList() => {
|
||||||
types,
|
types,
|
||||||
challenges,
|
challenges,
|
||||||
|
|
@ -168,10 +131,10 @@ class MonsterItems extends FilteredItems {
|
||||||
|
|
||||||
Item itemFromMap(Map<String, dynamic> map) {
|
Item itemFromMap(Map<String, dynamic> map) {
|
||||||
switch(map["ItemType"]) {
|
switch(map["ItemType"]) {
|
||||||
case "MonsterItem": return MonsterItem.fromMap(map);
|
case "MonsterItem": return MonsterItem(map);
|
||||||
case "MonsterItems": return MonsterItems.fromMap(map);
|
case "MonsterItems": return MonsterItems(map);
|
||||||
}
|
}
|
||||||
return Item.fromMap(map);
|
return Item(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Item> itemsFromMapList(List<Map<String, dynamic>> mapList) {
|
List<Item> itemsFromMapList(List<Map<String, dynamic>> mapList) {
|
||||||
|
|
|
||||||
0
aidedejeu_flutter/lib/widgets/about.dart
Normal file
0
aidedejeu_flutter/lib/widgets/about.dart
Normal file
|
|
@ -8,7 +8,7 @@ class RangeFilter extends StatefulWidget {
|
||||||
final ValueChanged<RangeValues> updateRangeValues;
|
final ValueChanged<RangeValues> updateRangeValues;
|
||||||
|
|
||||||
RangeFilter(
|
RangeFilter(
|
||||||
{@required this.values, this.rangeValues, this.updateRangeValues});
|
{Key key, @required this.values, this.rangeValues, this.updateRangeValues}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
|
|
@ -40,7 +40,7 @@ class ChipListFilter extends StatefulWidget {
|
||||||
final Set<String> selectedChoices;
|
final Set<String> selectedChoices;
|
||||||
final ValueChanged<Set<String>> updateSelectedChoices;
|
final ValueChanged<Set<String>> updateSelectedChoices;
|
||||||
|
|
||||||
ChipListFilter({this.choices, this.selectedChoices, this.updateSelectedChoices});
|
ChipListFilter({Key key, this.choices, this.selectedChoices, this.updateSelectedChoices}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
|
|
@ -85,7 +85,7 @@ class _ChipListFilterState extends State<ChipListFilter> {
|
||||||
class ChipFilter extends StatefulWidget {
|
class ChipFilter extends StatefulWidget {
|
||||||
final String label;
|
final String label;
|
||||||
|
|
||||||
ChipFilter({this.label});
|
ChipFilter({Key key, this.label}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
|
|
|
||||||
|
|
@ -1,268 +1,65 @@
|
||||||
import 'package:aidedejeu_flutter/database.dart';
|
import 'package:aidedejeu_flutter/database.dart';
|
||||||
|
import 'package:aidedejeu_flutter/models/filters.dart';
|
||||||
import 'package:aidedejeu_flutter/widgets/filters.dart';
|
import 'package:aidedejeu_flutter/widgets/filters.dart';
|
||||||
import 'package:aidedejeu_flutter/models/items.dart';
|
import 'package:aidedejeu_flutter/models/items.dart';
|
||||||
|
import 'package:aidedejeu_flutter/widgets/library.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
class MyHomePage extends StatefulWidget {
|
class HomePage extends StatelessWidget {
|
||||||
MyHomePage({Key key, @required this.id}) : super(key: key);
|
HomePage({Key key}) : super(key: key);
|
||||||
|
|
||||||
final String id;
|
|
||||||
|
|
||||||
@override
|
|
||||||
_MyHomePageState createState() => _MyHomePageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
|
||||||
void setItem(Item item) {
|
|
||||||
setState(() {
|
|
||||||
this.item = item;
|
|
||||||
if (item is FilteredItems) {
|
|
||||||
this.filters = (item as FilteredItems).toFilterList();
|
|
||||||
} else {
|
|
||||||
this.filters = null;
|
|
||||||
}
|
|
||||||
this.markdown =
|
|
||||||
item.markdown.replaceAllMapped(RegExp(r'<!--.*?-->'), (match) {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
String markdown = "";
|
|
||||||
Item item = null;
|
|
||||||
MarkdownStyleSheet styleSheet;
|
|
||||||
List<Filter> filters = null;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
|
|
||||||
|
|
||||||
_loadItem().then((item) => setItem(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
@protected
|
|
||||||
@mustCallSuper
|
|
||||||
void didChangeDependencies() {
|
|
||||||
styleSheet = MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith(
|
|
||||||
tableColumnWidth: IntrinsicColumnWidth(),
|
|
||||||
tableCellsPadding: EdgeInsets.all(0.2),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Item> _loadItem() async {
|
|
||||||
var item = await getItemWithId(this.widget.id);
|
|
||||||
var items = await loadChildrenItems(item, filters);
|
|
||||||
//setItem(item);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMarkdown(BuildContext context) {
|
|
||||||
return Markdown(
|
|
||||||
data: markdown,
|
|
||||||
styleSheet: styleSheet,
|
|
||||||
onTapLink: (link) => Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => MyHomePage(id: link)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMarkdownBody(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
margin: const EdgeInsets.all(10.0),
|
|
||||||
child: MarkdownBody(
|
|
||||||
data: markdown,
|
|
||||||
styleSheet: styleSheet,
|
|
||||||
onTapLink: (link) => Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => MyHomePage(id: link)),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildChildTile(BuildContext context, Item item) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(item.name),
|
|
||||||
subtitle: Text(item.aliasText ?? ""),
|
|
||||||
onTap: () => Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => MyHomePage(id: item.id)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildLibraryPage() {
|
|
||||||
return Stack(
|
|
||||||
children: <Widget>[
|
|
||||||
ListView.builder(
|
|
||||||
itemCount: (item?.children?.length ?? 0) + 1,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return index == 0
|
|
||||||
? _buildMarkdownBody(context)
|
|
||||||
: _buildChildTile(context, item.children[index - 1]);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildBookmarksPage() {
|
|
||||||
return Text("Bookmarks");
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildSearchPage() {
|
|
||||||
return Text("Search");
|
|
||||||
}
|
|
||||||
|
|
||||||
BottomNavigationBarItem _buildBottomNavigationBarItem(
|
|
||||||
String title, String assetName) {
|
|
||||||
return BottomNavigationBarItem(
|
|
||||||
icon: SvgPicture.asset(
|
|
||||||
assetName,
|
|
||||||
height: 30.0,
|
|
||||||
width: 30.0,
|
|
||||||
allowDrawingOutsideViewBox: true,
|
|
||||||
),
|
|
||||||
title: Text(title),
|
|
||||||
activeIcon: SvgPicture.asset(
|
|
||||||
assetName,
|
|
||||||
height: 40.0,
|
|
||||||
width: 40.0,
|
|
||||||
allowDrawingOutsideViewBox: true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List _buildBottomNavigationBarItems() {
|
|
||||||
return <BottomNavigationBarItem>[
|
|
||||||
_buildBottomNavigationBarItem("Bibliothèque", "assets/spell-book.svg"),
|
|
||||||
_buildBottomNavigationBarItem("Favoris", "assets/stars-stack.svg"),
|
|
||||||
_buildBottomNavigationBarItem("Recherche", "assets/crystal-ball.svg"),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildChoiceFilter(Filter filter) {
|
|
||||||
return ChipListFilter(
|
|
||||||
choices: filter.values,
|
|
||||||
selectedChoices: filter.selectedValues,
|
|
||||||
updateSelectedChoices: (Set<String> choices) {
|
|
||||||
setState(() {
|
|
||||||
filter.selectedValues = choices;
|
|
||||||
});
|
|
||||||
loadChildrenItems(item, filters).then((value) => {
|
|
||||||
setState(() {
|
|
||||||
this.item = item;
|
|
||||||
this.filters = filters;
|
|
||||||
})
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildRangeFilter(Filter filter) {
|
|
||||||
return RangeFilter(
|
|
||||||
values: filter.values,
|
|
||||||
rangeValues: filter.rangeValues,
|
|
||||||
updateRangeValues: (RangeValues values) {
|
|
||||||
setState(() {
|
|
||||||
filter.rangeValues = values;
|
|
||||||
});
|
|
||||||
loadChildrenItems(item, filters).then((value) => {
|
|
||||||
setState(() {
|
|
||||||
this.item = item;
|
|
||||||
this.filters = filters;
|
|
||||||
})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildFilter(Filter filter) {
|
|
||||||
return Column(children: <Widget>[
|
|
||||||
Divider(
|
|
||||||
color: Colors.blueGrey,
|
|
||||||
height: 10.0,
|
|
||||||
),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Text(filter.name),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
child: filter.type == FilterType.Choices
|
|
||||||
? _buildChoiceFilter(filter)
|
|
||||||
: _buildRangeFilter(filter))
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> _buildFilterList() {
|
|
||||||
return filters.map((filter) => _buildFilter(filter)).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
int indexPage = 0;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
print("build");
|
|
||||||
Widget currentPage;
|
|
||||||
switch (indexPage) {
|
|
||||||
case 0:
|
|
||||||
currentPage = _buildLibraryPage();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
currentPage = _buildBookmarksPage();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
currentPage = _buildSearchPage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
//appBar: AppBar(
|
appBar: AppBar(title: Text("Haches & Dés"),),
|
||||||
// title: Text(widget.id),
|
body: Column(
|
||||||
//),
|
children: <Widget>[
|
||||||
body: currentPage,
|
FlatButton.icon(
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
label: Text("Bibliothèque"),
|
||||||
currentIndex: indexPage,
|
icon: SvgPicture.asset(
|
||||||
onTap: (int index) {
|
"assets/spell-book.svg",
|
||||||
setState(() {
|
height: 100.0,
|
||||||
this.indexPage = index;
|
width: 100.0,
|
||||||
});
|
allowDrawingOutsideViewBox: true,
|
||||||
},
|
),
|
||||||
items: _buildBottomNavigationBarItems(),
|
onPressed: () => Navigator.push(
|
||||||
),
|
context,
|
||||||
endDrawer: filters != null
|
MaterialPageRoute(
|
||||||
? Drawer(
|
builder: (context) => LibraryPage(id: 'index.md')),
|
||||||
child: ListView(
|
),
|
||||||
// Important: Remove any padding from the ListView.
|
),
|
||||||
padding: EdgeInsets.zero,
|
FlatButton.icon(
|
||||||
children: _buildFilterList()),
|
label: Text("Personnages"),
|
||||||
)
|
icon: SvgPicture.asset(
|
||||||
: null,
|
"assets/swordman.svg",
|
||||||
appBar: AppBar(
|
height: 100.0,
|
||||||
title: Text(widget.id),
|
width: 100.0,
|
||||||
actions: filters != null
|
allowDrawingOutsideViewBox: true,
|
||||||
? [
|
),
|
||||||
Builder(
|
onPressed: () => Navigator.push(
|
||||||
builder: (context) => IconButton(
|
context,
|
||||||
icon: SvgPicture.asset(
|
MaterialPageRoute(
|
||||||
"assets/funnel.svg",
|
builder: (context) => LibraryPage(id: 'index.md')),
|
||||||
height: 30.0,
|
),
|
||||||
width: 30.0,
|
),
|
||||||
allowDrawingOutsideViewBox: true,
|
FlatButton.icon(
|
||||||
), //Icon(Icons.filter),
|
label: Text("A propos de..."),
|
||||||
onPressed: () => Scaffold.of(context).openEndDrawer(),
|
icon: SvgPicture.asset(
|
||||||
tooltip:
|
"assets/wooden-sign.svg",
|
||||||
MaterialLocalizations.of(context).openAppDrawerTooltip,
|
height: 100.0,
|
||||||
),
|
width: 100.0,
|
||||||
),
|
allowDrawingOutsideViewBox: true,
|
||||||
]
|
),
|
||||||
: null,
|
onPressed: () => Navigator.push(
|
||||||
),
|
context,
|
||||||
);
|
MaterialPageRoute(
|
||||||
|
builder: (context) => LibraryPage(id: 'index.md')),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
269
aidedejeu_flutter/lib/widgets/library.dart
Normal file
269
aidedejeu_flutter/lib/widgets/library.dart
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
import 'package:aidedejeu_flutter/database.dart';
|
||||||
|
import 'package:aidedejeu_flutter/models/filters.dart';
|
||||||
|
import 'package:aidedejeu_flutter/widgets/filters.dart';
|
||||||
|
import 'package:aidedejeu_flutter/models/items.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
|
class LibraryPage extends StatefulWidget {
|
||||||
|
LibraryPage({Key key, @required this.id}) : super(key: key);
|
||||||
|
|
||||||
|
final String id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_LibraryPageState createState() => _LibraryPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LibraryPageState extends State<LibraryPage> {
|
||||||
|
void setItem(Item item) {
|
||||||
|
setState(() {
|
||||||
|
this.item = item;
|
||||||
|
if (item is FilteredItems) {
|
||||||
|
this.filters = (item as FilteredItems).toFilterList();
|
||||||
|
} else {
|
||||||
|
this.filters = null;
|
||||||
|
}
|
||||||
|
this.markdown =
|
||||||
|
item.markdown.replaceAllMapped(RegExp(r'<!--.*?-->'), (match) {
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
String markdown = "";
|
||||||
|
Item item = null;
|
||||||
|
MarkdownStyleSheet styleSheet;
|
||||||
|
List<Filter> filters = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
|
||||||
|
_loadItem().then((item) => setItem(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
@mustCallSuper
|
||||||
|
void didChangeDependencies() {
|
||||||
|
styleSheet = MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith(
|
||||||
|
tableColumnWidth: IntrinsicColumnWidth(),
|
||||||
|
tableCellsPadding: EdgeInsets.all(0.2),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Item> _loadItem() async {
|
||||||
|
var item = await getItemWithId(this.widget.id);
|
||||||
|
var items = await loadChildrenItems(item, filters);
|
||||||
|
//setItem(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildMarkdown(BuildContext context) {
|
||||||
|
return Markdown(
|
||||||
|
data: markdown,
|
||||||
|
styleSheet: styleSheet,
|
||||||
|
onTapLink: (link) => Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => LibraryPage(id: link)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildMarkdownBody(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.all(10.0),
|
||||||
|
child: MarkdownBody(
|
||||||
|
data: markdown,
|
||||||
|
styleSheet: styleSheet,
|
||||||
|
onTapLink: (link) => Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => LibraryPage(id: link)),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildChildTile(BuildContext context, Item item) {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(item.name),
|
||||||
|
subtitle: Text(item.aliasText ?? ""),
|
||||||
|
onTap: () => Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => LibraryPage(id: item.id)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLibraryItemPage() {
|
||||||
|
return Stack(
|
||||||
|
children: <Widget>[
|
||||||
|
ListView.builder(
|
||||||
|
itemCount: (item?.children?.length ?? 0) + 1,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return index == 0
|
||||||
|
? _buildMarkdownBody(context)
|
||||||
|
: _buildChildTile(context, item.children[index - 1]);
|
||||||
|
})
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBookmarksPage() {
|
||||||
|
return Text("Bookmarks");
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSearchPage() {
|
||||||
|
return Text("Search");
|
||||||
|
}
|
||||||
|
|
||||||
|
BottomNavigationBarItem _buildBottomNavigationBarItem(
|
||||||
|
String title, String assetName) {
|
||||||
|
return BottomNavigationBarItem(
|
||||||
|
icon: SvgPicture.asset(
|
||||||
|
assetName,
|
||||||
|
height: 30.0,
|
||||||
|
width: 30.0,
|
||||||
|
allowDrawingOutsideViewBox: true,
|
||||||
|
),
|
||||||
|
title: Text(title),
|
||||||
|
activeIcon: SvgPicture.asset(
|
||||||
|
assetName,
|
||||||
|
height: 40.0,
|
||||||
|
width: 40.0,
|
||||||
|
allowDrawingOutsideViewBox: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List _buildBottomNavigationBarItems() {
|
||||||
|
return <BottomNavigationBarItem>[
|
||||||
|
_buildBottomNavigationBarItem("Bibliothèque", "assets/spell-book.svg"),
|
||||||
|
_buildBottomNavigationBarItem("Favoris", "assets/stars-stack.svg"),
|
||||||
|
_buildBottomNavigationBarItem("Recherche", "assets/crystal-ball.svg"),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildChoiceFilter(Filter filter) {
|
||||||
|
return ChipListFilter(
|
||||||
|
choices: filter.values,
|
||||||
|
selectedChoices: filter.selectedValues,
|
||||||
|
updateSelectedChoices: (Set<String> choices) {
|
||||||
|
setState(() {
|
||||||
|
filter.selectedValues = choices;
|
||||||
|
});
|
||||||
|
loadChildrenItems(item, filters).then((value) => {
|
||||||
|
setState(() {
|
||||||
|
this.item = item;
|
||||||
|
this.filters = filters;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildRangeFilter(Filter filter) {
|
||||||
|
return RangeFilter(
|
||||||
|
values: filter.values,
|
||||||
|
rangeValues: filter.rangeValues,
|
||||||
|
updateRangeValues: (RangeValues values) {
|
||||||
|
setState(() {
|
||||||
|
filter.rangeValues = values;
|
||||||
|
});
|
||||||
|
loadChildrenItems(item, filters).then((value) => {
|
||||||
|
setState(() {
|
||||||
|
this.item = item;
|
||||||
|
this.filters = filters;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildFilter(Filter filter) {
|
||||||
|
return Column(children: <Widget>[
|
||||||
|
Divider(
|
||||||
|
color: Colors.blueGrey,
|
||||||
|
height: 10.0,
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text(filter.name),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
child: filter.type == FilterType.Choices
|
||||||
|
? _buildChoiceFilter(filter)
|
||||||
|
: _buildRangeFilter(filter))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildFilterList() {
|
||||||
|
return filters.map((filter) => _buildFilter(filter)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
int indexPage = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
print("build");
|
||||||
|
Widget currentPage;
|
||||||
|
switch (indexPage) {
|
||||||
|
case 0:
|
||||||
|
currentPage = _buildLibraryItemPage();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
currentPage = _buildBookmarksPage();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
currentPage = _buildSearchPage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
//appBar: AppBar(
|
||||||
|
// title: Text(widget.id),
|
||||||
|
//),
|
||||||
|
body: currentPage,
|
||||||
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
|
currentIndex: indexPage,
|
||||||
|
onTap: (int index) {
|
||||||
|
setState(() {
|
||||||
|
this.indexPage = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
items: _buildBottomNavigationBarItems(),
|
||||||
|
),
|
||||||
|
endDrawer: filters != null
|
||||||
|
? Drawer(
|
||||||
|
child: ListView(
|
||||||
|
// Important: Remove any padding from the ListView.
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
children: _buildFilterList()),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(widget.id),
|
||||||
|
actions: filters != null
|
||||||
|
? [
|
||||||
|
Builder(
|
||||||
|
builder: (context) => IconButton(
|
||||||
|
icon: SvgPicture.asset(
|
||||||
|
"assets/funnel.svg",
|
||||||
|
height: 30.0,
|
||||||
|
width: 30.0,
|
||||||
|
allowDrawingOutsideViewBox: true,
|
||||||
|
), //Icon(Icons.filter),
|
||||||
|
onPressed: () => Scaffold.of(context).openEndDrawer(),
|
||||||
|
tooltip:
|
||||||
|
MaterialLocalizations.of(context).openAppDrawerTooltip,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
0
aidedejeu_flutter/lib/widgets/pceditor.dart
Normal file
0
aidedejeu_flutter/lib/widgets/pceditor.dart
Normal file
Loading…
Add table
Add a link
Reference in a new issue