Allow configuring the Home Screen

It can either be the Folders view or the All Notes view.
This commit is contained in:
Vishesh Handa
2020-05-08 19:30:25 +02:00
parent cc45894a07
commit faf561f104
8 changed files with 137 additions and 62 deletions

View File

@ -13,6 +13,7 @@ settings:
display:
title: Display Settings
darkTheme: Dark Theme
homeScreen: Home Screen
gitAuthor: Git Author Settings
versionInfo: Version Info
analytics: Analytics
@ -23,3 +24,4 @@ settings:
editors:
checklist:
add: Add Item
pro: Pro

View File

@ -143,6 +143,9 @@ class JournalApp extends StatelessWidget {
if (!stateContainer.appState.onBoardingCompleted) {
initialRoute = '/onBoarding';
}
if (Settings.instance.homeScreen == SettingsHomeScreen.AllFolders) {
initialRoute = '/folders';
}
return MaterialApp(
key: const ValueKey("App"),

View File

@ -1,3 +1,4 @@
import 'package:gitjournal/app.dart';
import 'package:gitjournal/utils/logger.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
@ -13,6 +14,10 @@ class InAppPurchases {
return;
}
if (JournalApp.isInDebugMode) {
return;
}
Purchases.setDebugLogsEnabled(false);
await Purchases.setup(
environment['revenueCat'],

View File

@ -50,20 +50,22 @@ class SettingsEditorsScreenState extends State<SettingsEditorsScreen> {
),
if (Features.purchaseProModeAvailable) SettingsHeader("Journal Editor"),
if (Features.purchaseProModeAvailable)
ProListTile(
title: const Text("Default Folder"),
subtitle: Text(defaultNewFolder),
onTap: () async {
var destFolder = await showDialog<NotesFolderFS>(
context: context,
builder: (context) => FolderSelectionDialog(),
);
ProSettingOverlay(
child: ListTile(
title: const Text("Default Folder"),
subtitle: Text(defaultNewFolder),
onTap: () async {
var destFolder = await showDialog<NotesFolderFS>(
context: context,
builder: (context) => FolderSelectionDialog(),
);
Settings.instance.journalEditordefaultNewNoteFolderSpec =
destFolder != null ? destFolder.pathSpec() : "";
Settings.instance.save();
setState(() {});
},
Settings.instance.journalEditordefaultNewNoteFolderSpec =
destFolder != null ? destFolder.pathSpec() : "";
Settings.instance.save();
setState(() {});
},
),
),
]);

View File

@ -142,6 +142,21 @@ class SettingsListState extends State<SettingsList> {
dynamicTheme.setBrightness(b);
},
),
ProSettingOverlay(
child: ListPreference(
title: tr('settings.display.homeScreen'),
currentOption: settings.homeScreen.toPublicString(),
options: SettingsHomeScreen.options
.map((f) => f.toPublicString())
.toList(),
onChange: (String publicStr) {
var s = SettingsHomeScreen.fromPublicString(publicStr);
Settings.instance.homeScreen = s;
Settings.instance.save();
setState(() {});
},
),
),
SettingsHeader('Note Settings'),
ListTile(
title: const Text("Default Folder for new notes"),

View File

@ -1,3 +1,4 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gitjournal/settings.dart';
@ -63,32 +64,23 @@ class ListPreference extends StatelessWidget {
}
}
class ProListTile extends StatelessWidget {
final Widget title;
final Widget subtitle;
final Function onTap;
class ProSettingOverlay extends StatelessWidget {
final Widget child;
ProListTile({this.title, this.subtitle, this.onTap});
ProSettingOverlay({@required this.child});
@override
Widget build(BuildContext context) {
var isPro = Settings.instance.proMode;
var tile = ListTile(
title: title,
subtitle: subtitle,
onTap: onTap,
);
if (isPro) {
return tile;
if (Settings.instance.proMode) {
return child;
}
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: Banner(
message: 'Pro',
location: BannerLocation.topStart,
color: Colors.purple,
child: IgnorePointer(child: tile),
message: tr('pro'),
location: BannerLocation.topEnd,
color: Theme.of(context).accentColor,
child: IgnorePointer(child: Opacity(opacity: 0.5, child: child)),
),
onTap: () {
Navigator.pushNamed(context, "/purchase");

View File

@ -41,6 +41,8 @@ class Settings {
String _pseudoId;
String get pseudoId => _pseudoId;
SettingsHomeScreen homeScreen = SettingsHomeScreen.Default;
SettingsMarkdownDefaultView markdownDefaultView =
SettingsMarkdownDefaultView.Default;
@ -89,6 +91,9 @@ class Settings {
_pseudoId = Uuid().v4();
pref.setString("pseudoId", _pseudoId);
}
homeScreen =
SettingsHomeScreen.fromInternalString(pref.getString("homeScreen"));
}
Future save() async {
@ -115,6 +120,7 @@ class Settings {
pref.setString("proExpirationDate", proExpirationDate);
pref.setInt("settingsVersion", version);
pref.setBool("proMode", proMode);
pref.setString("homeScreen", homeScreen.toInternalString());
// Shouldn't we check if something has actually changed?
for (var f in changeObservers) {
@ -144,6 +150,7 @@ class Settings {
"proMode": proMode.toString(),
'pseudoId': pseudoId,
'markdownDefaultView': markdownDefaultView.toInternalString(),
'homeScreen': homeScreen.toInternalString(),
};
}
@ -466,3 +473,50 @@ class SettingsMarkdownDefaultView {
return "";
}
}
class SettingsHomeScreen {
static const AllNotes = SettingsHomeScreen("All Notes", "all_notes");
static const AllFolders = SettingsHomeScreen("All Folders", "all_folders");
static const Default = AllNotes;
final String _str;
final String _publicString;
const SettingsHomeScreen(this._publicString, this._str);
String toInternalString() {
return _str;
}
String toPublicString() {
return _publicString;
}
static const options = <SettingsHomeScreen>[
AllNotes,
AllFolders,
];
static SettingsHomeScreen fromInternalString(String str) {
for (var opt in options) {
if (opt.toInternalString() == str) {
return opt;
}
}
return Default;
}
static SettingsHomeScreen fromPublicString(String str) {
for (var opt in options) {
if (opt.toPublicString() == str) {
return opt;
}
}
return Default;
}
@override
String toString() {
assert(false, "SettingsHomeScreen toString should never be called");
return "";
}
}

View File

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/settings.dart';
import 'package:gitjournal/utils/logger.dart';
import 'package:launch_review/launch_review.dart';
import 'package:provider/provider.dart';
import 'package:share/share.dart';
@ -84,43 +85,14 @@ class AppDrawer extends StatelessWidget {
context,
icon: Icons.note,
title: "All Notes",
onTap: () {
var m = ModalRoute.of(context);
if (m.settings.name == "/") {
Navigator.pop(context);
} else {
Navigator.popUntil(
context, (route) => route.settings.name == '/');
}
},
onTap: () => _navTopLevel(context, '/'),
selected: currentRoute == '/',
),
_buildDrawerTile(
context,
icon: Icons.folder,
title: "Folders",
onTap: () {
var m = ModalRoute.of(context);
if (m.settings.name == '/') {
Navigator.pop(context);
Navigator.pushNamed(context, '/folders');
} else if (m.settings.name == '/folders') {
Navigator.pop(context);
} else {
// Check if '/folders' is a parent
var wasParent = false;
Navigator.popUntil(
context,
(route) {
wasParent = route.settings.name == '/folders';
return wasParent;
},
);
if (!wasParent) {
Navigator.pushNamed(context, '/folders');
}
}
},
onTap: () => _navTopLevel(context, '/folders'),
selected: currentRoute == "/folders",
),
divider,
@ -253,3 +225,33 @@ class AppDrawer extends StatelessWidget {
);
}
}
void _navTopLevel(BuildContext context, String toRoute) {
var fromRoute = ModalRoute.of(context).settings.name;
Log.i("Routing from $fromRoute -> $toRoute");
// Always first pop the AppBar
Navigator.pop(context);
if (fromRoute == toRoute) {
return;
}
var wasParent = false;
Navigator.popUntil(
context,
(route) {
if (route.isFirst) {
return true;
}
wasParent = route.settings.name == toRoute;
if (wasParent) {
Log.i("Router popping ${route.settings.name}");
}
return wasParent;
},
);
if (!wasParent) {
Navigator.pushNamed(context, toRoute);
}
}