mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-29 02:07:39 +08:00
Allow configuring the Home Screen
It can either be the Folders view or the All Notes view.
This commit is contained in:
@ -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
|
||||
|
@ -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"),
|
||||
|
@ -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'],
|
||||
|
@ -50,7 +50,8 @@ class SettingsEditorsScreenState extends State<SettingsEditorsScreen> {
|
||||
),
|
||||
if (Features.purchaseProModeAvailable) SettingsHeader("Journal Editor"),
|
||||
if (Features.purchaseProModeAvailable)
|
||||
ProListTile(
|
||||
ProSettingOverlay(
|
||||
child: ListTile(
|
||||
title: const Text("Default Folder"),
|
||||
subtitle: Text(defaultNewFolder),
|
||||
onTap: () async {
|
||||
@ -65,6 +66,7 @@ class SettingsEditorsScreenState extends State<SettingsEditorsScreen> {
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
return Scaffold(
|
||||
|
@ -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"),
|
||||
|
@ -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");
|
||||
|
@ -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 "";
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user