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:
|
display:
|
||||||
title: Display Settings
|
title: Display Settings
|
||||||
darkTheme: Dark Theme
|
darkTheme: Dark Theme
|
||||||
|
homeScreen: Home Screen
|
||||||
gitAuthor: Git Author Settings
|
gitAuthor: Git Author Settings
|
||||||
versionInfo: Version Info
|
versionInfo: Version Info
|
||||||
analytics: Analytics
|
analytics: Analytics
|
||||||
@ -23,3 +24,4 @@ settings:
|
|||||||
editors:
|
editors:
|
||||||
checklist:
|
checklist:
|
||||||
add: Add Item
|
add: Add Item
|
||||||
|
pro: Pro
|
||||||
|
@ -143,6 +143,9 @@ class JournalApp extends StatelessWidget {
|
|||||||
if (!stateContainer.appState.onBoardingCompleted) {
|
if (!stateContainer.appState.onBoardingCompleted) {
|
||||||
initialRoute = '/onBoarding';
|
initialRoute = '/onBoarding';
|
||||||
}
|
}
|
||||||
|
if (Settings.instance.homeScreen == SettingsHomeScreen.AllFolders) {
|
||||||
|
initialRoute = '/folders';
|
||||||
|
}
|
||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
key: const ValueKey("App"),
|
key: const ValueKey("App"),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:gitjournal/app.dart';
|
||||||
import 'package:gitjournal/utils/logger.dart';
|
import 'package:gitjournal/utils/logger.dart';
|
||||||
import 'package:purchases_flutter/purchases_flutter.dart';
|
import 'package:purchases_flutter/purchases_flutter.dart';
|
||||||
|
|
||||||
@ -13,6 +14,10 @@ class InAppPurchases {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (JournalApp.isInDebugMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Purchases.setDebugLogsEnabled(false);
|
Purchases.setDebugLogsEnabled(false);
|
||||||
await Purchases.setup(
|
await Purchases.setup(
|
||||||
environment['revenueCat'],
|
environment['revenueCat'],
|
||||||
|
@ -50,7 +50,8 @@ class SettingsEditorsScreenState extends State<SettingsEditorsScreen> {
|
|||||||
),
|
),
|
||||||
if (Features.purchaseProModeAvailable) SettingsHeader("Journal Editor"),
|
if (Features.purchaseProModeAvailable) SettingsHeader("Journal Editor"),
|
||||||
if (Features.purchaseProModeAvailable)
|
if (Features.purchaseProModeAvailable)
|
||||||
ProListTile(
|
ProSettingOverlay(
|
||||||
|
child: ListTile(
|
||||||
title: const Text("Default Folder"),
|
title: const Text("Default Folder"),
|
||||||
subtitle: Text(defaultNewFolder),
|
subtitle: Text(defaultNewFolder),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
@ -65,6 +66,7 @@ class SettingsEditorsScreenState extends State<SettingsEditorsScreen> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -142,6 +142,21 @@ class SettingsListState extends State<SettingsList> {
|
|||||||
dynamicTheme.setBrightness(b);
|
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'),
|
SettingsHeader('Note Settings'),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text("Default Folder for new notes"),
|
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:flutter/material.dart';
|
||||||
import 'package:gitjournal/settings.dart';
|
import 'package:gitjournal/settings.dart';
|
||||||
|
|
||||||
@ -63,32 +64,23 @@ class ListPreference extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProListTile extends StatelessWidget {
|
class ProSettingOverlay extends StatelessWidget {
|
||||||
final Widget title;
|
final Widget child;
|
||||||
final Widget subtitle;
|
|
||||||
final Function onTap;
|
|
||||||
|
|
||||||
ProListTile({this.title, this.subtitle, this.onTap});
|
ProSettingOverlay({@required this.child});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var isPro = Settings.instance.proMode;
|
if (Settings.instance.proMode) {
|
||||||
var tile = ListTile(
|
return child;
|
||||||
title: title,
|
|
||||||
subtitle: subtitle,
|
|
||||||
onTap: onTap,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isPro) {
|
|
||||||
return tile;
|
|
||||||
}
|
}
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: Banner(
|
child: Banner(
|
||||||
message: 'Pro',
|
message: tr('pro'),
|
||||||
location: BannerLocation.topStart,
|
location: BannerLocation.topEnd,
|
||||||
color: Colors.purple,
|
color: Theme.of(context).accentColor,
|
||||||
child: IgnorePointer(child: tile),
|
child: IgnorePointer(child: Opacity(opacity: 0.5, child: child)),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(context, "/purchase");
|
Navigator.pushNamed(context, "/purchase");
|
||||||
|
@ -41,6 +41,8 @@ class Settings {
|
|||||||
String _pseudoId;
|
String _pseudoId;
|
||||||
String get pseudoId => _pseudoId;
|
String get pseudoId => _pseudoId;
|
||||||
|
|
||||||
|
SettingsHomeScreen homeScreen = SettingsHomeScreen.Default;
|
||||||
|
|
||||||
SettingsMarkdownDefaultView markdownDefaultView =
|
SettingsMarkdownDefaultView markdownDefaultView =
|
||||||
SettingsMarkdownDefaultView.Default;
|
SettingsMarkdownDefaultView.Default;
|
||||||
|
|
||||||
@ -89,6 +91,9 @@ class Settings {
|
|||||||
_pseudoId = Uuid().v4();
|
_pseudoId = Uuid().v4();
|
||||||
pref.setString("pseudoId", _pseudoId);
|
pref.setString("pseudoId", _pseudoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
homeScreen =
|
||||||
|
SettingsHomeScreen.fromInternalString(pref.getString("homeScreen"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future save() async {
|
Future save() async {
|
||||||
@ -115,6 +120,7 @@ class Settings {
|
|||||||
pref.setString("proExpirationDate", proExpirationDate);
|
pref.setString("proExpirationDate", proExpirationDate);
|
||||||
pref.setInt("settingsVersion", version);
|
pref.setInt("settingsVersion", version);
|
||||||
pref.setBool("proMode", proMode);
|
pref.setBool("proMode", proMode);
|
||||||
|
pref.setString("homeScreen", homeScreen.toInternalString());
|
||||||
|
|
||||||
// Shouldn't we check if something has actually changed?
|
// Shouldn't we check if something has actually changed?
|
||||||
for (var f in changeObservers) {
|
for (var f in changeObservers) {
|
||||||
@ -144,6 +150,7 @@ class Settings {
|
|||||||
"proMode": proMode.toString(),
|
"proMode": proMode.toString(),
|
||||||
'pseudoId': pseudoId,
|
'pseudoId': pseudoId,
|
||||||
'markdownDefaultView': markdownDefaultView.toInternalString(),
|
'markdownDefaultView': markdownDefaultView.toInternalString(),
|
||||||
|
'homeScreen': homeScreen.toInternalString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,3 +473,50 @@ class SettingsMarkdownDefaultView {
|
|||||||
return "";
|
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:flutter_email_sender/flutter_email_sender.dart';
|
||||||
import 'package:gitjournal/features.dart';
|
import 'package:gitjournal/features.dart';
|
||||||
import 'package:gitjournal/settings.dart';
|
import 'package:gitjournal/settings.dart';
|
||||||
|
import 'package:gitjournal/utils/logger.dart';
|
||||||
import 'package:launch_review/launch_review.dart';
|
import 'package:launch_review/launch_review.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:share/share.dart';
|
import 'package:share/share.dart';
|
||||||
@ -84,43 +85,14 @@ class AppDrawer extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
icon: Icons.note,
|
icon: Icons.note,
|
||||||
title: "All Notes",
|
title: "All Notes",
|
||||||
onTap: () {
|
onTap: () => _navTopLevel(context, '/'),
|
||||||
var m = ModalRoute.of(context);
|
|
||||||
if (m.settings.name == "/") {
|
|
||||||
Navigator.pop(context);
|
|
||||||
} else {
|
|
||||||
Navigator.popUntil(
|
|
||||||
context, (route) => route.settings.name == '/');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selected: currentRoute == '/',
|
selected: currentRoute == '/',
|
||||||
),
|
),
|
||||||
_buildDrawerTile(
|
_buildDrawerTile(
|
||||||
context,
|
context,
|
||||||
icon: Icons.folder,
|
icon: Icons.folder,
|
||||||
title: "Folders",
|
title: "Folders",
|
||||||
onTap: () {
|
onTap: () => _navTopLevel(context, '/folders'),
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selected: currentRoute == "/folders",
|
selected: currentRoute == "/folders",
|
||||||
),
|
),
|
||||||
divider,
|
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