mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-29 18:38:36 +08:00
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:
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user