Allow the StandardFolderView to be customized

The customization screen is very ugly and this entire thing feels
extremely hacky with the abstractions leaking out everywhere. However,
it does work.

I'll clean it up another day.
This commit is contained in:
Vishesh Handa
2020-03-11 14:48:32 +01:00
parent d2b6b0eb08
commit 7aea2611bf
4 changed files with 201 additions and 30 deletions

View File

@ -18,6 +18,8 @@ Widget buildFolderView(
FolderViewType viewType,
NotesFolderReadOnly folder,
String emptyText,
StandardViewHeader header,
bool showSummary,
) {
var noteSelectionFn = (Note note) async {
var route = MaterialPageRoute(
@ -38,6 +40,8 @@ Widget buildFolderView(
folder: folder,
noteSelectedFunction: noteSelectionFn,
emptyText: emptyText,
headerType: header,
showSummary: showSummary,
);
case FolderViewType.Journal:
return JournalView(

View File

@ -7,15 +7,26 @@ import 'package:intl/intl.dart';
import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/core/notes_folder.dart';
enum StandardViewHeader {
TitleOrFileName,
FileName,
TitleGenerated,
}
class StandardView extends StatelessWidget {
final NoteSelectedFunction noteSelectedFunction;
final NotesFolderReadOnly folder;
final String emptyText;
final StandardViewHeader headerType;
final bool showSummary;
StandardView({
@required this.folder,
@required this.noteSelectedFunction,
@required this.emptyText,
@required this.headerType,
@required this.showSummary,
});
@override
@ -32,13 +43,32 @@ class StandardView extends StatelessWidget {
Widget _buildRow(BuildContext context, Note note) {
var textTheme = Theme.of(context).textTheme;
var title = note.title;
if (title == null || title.isEmpty) {
title = note.fileName;
String title;
switch (headerType) {
case StandardViewHeader.TitleOrFileName:
title = note.title;
if (title == null || title.isEmpty) {
title = note.fileName;
}
break;
case StandardViewHeader.FileName:
title = note.fileName;
break;
case StandardViewHeader.TitleGenerated:
title = note.summary;
break;
default:
assert(false, "StandardViewHeader must not be null");
}
var titleTheme =
textTheme.title.copyWith(fontSize: textTheme.title.fontSize * 0.95);
Widget titleWidget = Text(title, style: titleTheme);
Widget titleWidget = Text(
title,
style: textTheme.title,
overflow: TextOverflow.ellipsis,
);
Widget trailing = Container();
var date = note.modified ?? note.created;
@ -48,16 +78,6 @@ class StandardView extends StatelessWidget {
trailing = Text(dateStr, style: textTheme.caption);
}
var children = <Widget>[
const SizedBox(height: 8.0),
Text(
note.summary,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: textTheme.body1,
),
];
var titleRow = Row(
children: <Widget>[Expanded(child: titleWidget), trailing],
mainAxisAlignment: MainAxisAlignment.start,
@ -65,15 +85,34 @@ class StandardView extends StatelessWidget {
textBaseline: TextBaseline.alphabetic,
);
var tile = ListTile(
isThreeLine: true,
title: titleRow,
subtitle: Column(
children: children,
crossAxisAlignment: CrossAxisAlignment.start,
),
onTap: () => noteSelectedFunction(note),
);
ListTile tile;
if (showSummary) {
var summary = <Widget>[
const SizedBox(height: 8.0),
Text(
note.summary,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: textTheme.body1,
),
];
tile = ListTile(
isThreeLine: true,
title: titleRow,
subtitle: Column(
children: summary,
crossAxisAlignment: CrossAxisAlignment.start,
),
onTap: () => noteSelectedFunction(note),
);
} else {
tile = ListTile(
isThreeLine: false,
title: titleRow,
onTap: () => noteSelectedFunction(note),
);
}
var dc = Theme.of(context).dividerColor;
var divider = Container(
@ -81,6 +120,16 @@ class StandardView extends StatelessWidget {
child: Divider(color: dc.withOpacity(dc.opacity / 3)),
);
if (!showSummary) {
return Column(
children: <Widget>[
divider,
tile,
divider,
],
);
}
return Column(
children: <Widget>[
divider,

View File

@ -3,7 +3,9 @@ import 'package:flutter/material.dart';
import 'package:gitjournal/core/notes_folder.dart';
import 'package:gitjournal/core/sorted_notes_folder.dart';
import 'package:gitjournal/core/sorting_mode.dart';
import 'package:gitjournal/folder_views/standard_view.dart';
import 'package:gitjournal/screens/note_editor.dart';
import 'package:gitjournal/screens/settings_screen.dart';
import 'package:gitjournal/settings.dart';
import 'package:gitjournal/state_container.dart';
import 'package:gitjournal/utils.dart';
@ -15,6 +17,11 @@ import 'package:gitjournal/folder_views/common.dart';
import 'package:provider/provider.dart';
enum DropDownChoices {
SortingOptions,
ViewOptions,
}
class FolderView extends StatefulWidget {
final NotesFolder notesFolder;
@ -28,6 +35,9 @@ class _FolderViewState extends State<FolderView> {
SortedNotesFolder sortedNotesFolder;
FolderViewType _viewType = FolderViewType.Standard;
StandardViewHeader _headerType = StandardViewHeader.TitleGenerated;
bool _showSummary = true;
@override
void initState() {
super.initState();
@ -69,10 +79,37 @@ class _FolderViewState extends State<FolderView> {
_viewType,
sortedNotesFolder,
emptyText,
_headerType,
_showSummary,
);
},
);
var extraAction = PopupMenuButton<DropDownChoices>(
onSelected: (DropDownChoices choice) {
switch (choice) {
case DropDownChoices.SortingOptions:
_sortButtonPressed();
break;
case DropDownChoices.ViewOptions:
_configureViewButtonPressed();
break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<DropDownChoices>>[
const PopupMenuItem<DropDownChoices>(
value: DropDownChoices.SortingOptions,
child: Text('Sorting Options'),
),
if (_viewType == FolderViewType.Standard)
const PopupMenuItem<DropDownChoices>(
value: DropDownChoices.ViewOptions,
child: Text('View Options'),
),
],
);
return Scaffold(
appBar: AppBar(
title: Text(title),
@ -95,10 +132,7 @@ class _FolderViewState extends State<FolderView> {
);
},
),
IconButton(
icon: Icon(Icons.sort),
onPressed: _sortButtonPressed,
),
extraAction,
],
),
floatingActionButton: createButton,
@ -167,6 +201,82 @@ class _FolderViewState extends State<FolderView> {
}
}
void _configureViewButtonPressed() async {
await showDialog<SortingMode>(
context: context,
builder: (BuildContext context) {
var headerTypeChanged = (StandardViewHeader newHeader) {
setState(() {
print("CHanging headerType to $newHeader");
_headerType = newHeader;
});
};
var summaryChanged = (bool newVal) {
setState(() {
_showSummary = newVal;
});
};
return StatefulBuilder(
builder: (BuildContext context, Function setState) {
var children = <Widget>[
SettingsHeader("Header Options"),
RadioListTile<StandardViewHeader>(
title: const Text("Title or FileName"),
value: StandardViewHeader.TitleOrFileName,
groupValue: _headerType,
onChanged: (newVal) {
headerTypeChanged(newVal);
setState(() {});
},
),
RadioListTile<StandardViewHeader>(
title: const Text("Auto Generated Title"),
value: StandardViewHeader.TitleGenerated,
groupValue: _headerType,
onChanged: (newVal) {
headerTypeChanged(newVal);
setState(() {});
},
),
RadioListTile<StandardViewHeader>(
title: const Text("FileName"),
value: StandardViewHeader.FileName,
groupValue: _headerType,
onChanged: (newVal) {
headerTypeChanged(newVal);
setState(() {});
},
),
SwitchListTile(
title: const Text("Show Summary"),
value: _showSummary,
onChanged: (bool newVal) {
setState(() {
_showSummary = newVal;
});
summaryChanged(newVal);
},
),
];
return AlertDialog(
title: const Text("Customize View"),
content: Column(
children: children,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
),
);
},
);
},
);
setState(() {});
}
void _folderViewChooserSelected() async {
var onViewChange = (FolderViewType vt) => Navigator.of(context).pop(vt);

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/core/virtual_notes_folder.dart';
import 'package:gitjournal/folder_views/standard_view.dart';
import 'package:gitjournal/themes.dart';
import 'package:gitjournal/folder_views/common.dart';
@ -74,6 +75,13 @@ class NoteSearchDelegate extends SearchDelegate<Note> {
var folder = VirtualNotesFolder(filteredNotes);
const emptyText = "No Search Results Found";
return buildFolderView(context, viewType, folder, emptyText);
return buildFolderView(
context,
viewType,
folder,
emptyText,
StandardViewHeader.TitleOrFileName,
true,
);
}
}