mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-07-01 12:23:44 +08:00
Move all persistent state from AppState to Settings
This way all the persistant state of the app is managed from the same place. It makes everything much easier. Also, it's required for when GitJournal supports multiple repositories.
This commit is contained in:
33
lib/app.dart
33
lib/app.dart
@ -15,7 +15,6 @@ import 'package:path_provider/path_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:quick_actions/quick_actions.dart';
|
||||
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:gitjournal/analytics.dart';
|
||||
import 'package:gitjournal/appstate.dart';
|
||||
@ -41,12 +40,10 @@ import 'setup/screens.dart';
|
||||
class JournalApp extends StatefulWidget {
|
||||
final AppState appState;
|
||||
|
||||
static Future main(SharedPreferences pref) async {
|
||||
static Future main() async {
|
||||
await Log.init();
|
||||
|
||||
var appState = AppState(pref);
|
||||
appState.dumpToLog();
|
||||
|
||||
var appState = AppState();
|
||||
var settings = Settings.instance;
|
||||
Log.i("Setting ${settings.toLoggableMap()}");
|
||||
|
||||
@ -54,38 +51,38 @@ class JournalApp extends StatefulWidget {
|
||||
_enableAnalyticsIfPossible(settings);
|
||||
}
|
||||
|
||||
if (appState.gitBaseDirectory.isEmpty) {
|
||||
if (settings.gitBaseDirectory.isEmpty) {
|
||||
var dir = await getApplicationDocumentsDirectory();
|
||||
appState.gitBaseDirectory = dir.path;
|
||||
appState.save(pref);
|
||||
settings.gitBaseDirectory = dir.path;
|
||||
settings.save();
|
||||
}
|
||||
|
||||
if (!Directory(appState.gitBaseDirectory).existsSync()) {
|
||||
if (!Directory(settings.gitBaseDirectory).existsSync()) {
|
||||
Log.w("Applications Documents Directory no longer exists");
|
||||
var dir = await getApplicationDocumentsDirectory();
|
||||
appState.gitBaseDirectory = dir.path;
|
||||
appState.save(pref);
|
||||
settings.gitBaseDirectory = dir.path;
|
||||
settings.save();
|
||||
Log.i("New Documents Directory Path ${dir.path}");
|
||||
}
|
||||
|
||||
if (appState.localGitRepoConfigured == false) {
|
||||
if (settings.localGitRepoConfigured == false) {
|
||||
// FIXME: What about exceptions!
|
||||
appState.localGitRepoFolderName = "journal_local";
|
||||
settings.localGitRepoFolderName = "journal_local";
|
||||
var repoPath = p.join(
|
||||
appState.gitBaseDirectory,
|
||||
appState.localGitRepoFolderName,
|
||||
settings.gitBaseDirectory,
|
||||
settings.localGitRepoFolderName,
|
||||
);
|
||||
await GitRepository.init(repoPath);
|
||||
|
||||
appState.localGitRepoConfigured = true;
|
||||
appState.save(pref);
|
||||
settings.localGitRepoConfigured = true;
|
||||
settings.save();
|
||||
}
|
||||
|
||||
var app = ChangeNotifierProvider.value(
|
||||
value: settings,
|
||||
child: ChangeNotifierProvider(
|
||||
create: (_) {
|
||||
return StateContainer(appState);
|
||||
return StateContainer(appState, settings);
|
||||
},
|
||||
child: ChangeNotifierProvider(
|
||||
child: JournalApp(appState),
|
||||
|
@ -1,7 +1,4 @@
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:gitjournal/core/notes_folder_fs.dart';
|
||||
import 'package:gitjournal/utils/logger.dart';
|
||||
|
||||
enum SyncStatus {
|
||||
Unknown,
|
||||
@ -12,54 +9,12 @@ enum SyncStatus {
|
||||
}
|
||||
|
||||
class AppState {
|
||||
//
|
||||
// Saved on Disk
|
||||
//
|
||||
// FIXME: These should be figured out by querying the 'git remotes'
|
||||
String localGitRepoFolderName = "";
|
||||
bool localGitRepoConfigured = false;
|
||||
|
||||
String remoteGitRepoFolderName = "";
|
||||
bool remoteGitRepoConfigured = false;
|
||||
|
||||
SyncStatus syncStatus = SyncStatus.Unknown;
|
||||
int numChanges = 0;
|
||||
|
||||
//
|
||||
// Temporary
|
||||
//
|
||||
/// This is the directory where all the git repos are stored
|
||||
String gitBaseDirectory = "";
|
||||
|
||||
bool get hasJournalEntries {
|
||||
return notesFolder.hasNotes;
|
||||
}
|
||||
|
||||
NotesFolderFS notesFolder;
|
||||
|
||||
AppState(SharedPreferences pref) {
|
||||
localGitRepoConfigured = pref.getBool("localGitRepoConfigured") ?? false;
|
||||
remoteGitRepoConfigured = pref.getBool("remoteGitRepoConfigured") ?? false;
|
||||
localGitRepoFolderName = pref.getString("localGitRepoPath") ?? "";
|
||||
remoteGitRepoFolderName = pref.getString("remoteGitRepoPath") ?? "";
|
||||
gitBaseDirectory = pref.getString("gitBaseDirectory") ?? "";
|
||||
}
|
||||
|
||||
void dumpToLog() {
|
||||
Log.i(" ---- Settings ---- ");
|
||||
Log.i("localGitRepoConfigured: $localGitRepoConfigured");
|
||||
Log.i("remoteGitRepoConfigured: $remoteGitRepoConfigured");
|
||||
Log.i("localGitRepoFolderName: $localGitRepoFolderName");
|
||||
Log.i("remoteGitRepoFolderName: $remoteGitRepoFolderName");
|
||||
Log.i("gitBaseDirectory: $gitBaseDirectory");
|
||||
Log.i(" ------------------ ");
|
||||
}
|
||||
|
||||
Future save(SharedPreferences pref) async {
|
||||
await pref.setBool("localGitRepoConfigured", localGitRepoConfigured);
|
||||
await pref.setBool("remoteGitRepoConfigured", remoteGitRepoConfigured);
|
||||
await pref.setString("localGitRepoPath", localGitRepoFolderName);
|
||||
await pref.setString("remoteGitRepoPath", remoteGitRepoFolderName);
|
||||
await pref.setString("gitBaseDirectory", gitBaseDirectory);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,6 @@ void main() async {
|
||||
}).sendPort);
|
||||
|
||||
runZonedGuarded(() async {
|
||||
await JournalApp.main(pref);
|
||||
await JournalApp.main();
|
||||
}, reportError);
|
||||
}
|
||||
|
@ -372,7 +372,7 @@ class _FolderViewState extends State<FolderView> {
|
||||
}
|
||||
|
||||
List<Widget> _buildNoteActions() {
|
||||
final appState = Provider.of<StateContainer>(context).appState;
|
||||
final settings = Provider.of<Settings>(context);
|
||||
|
||||
var extraActions = PopupMenuButton<DropDownChoices>(
|
||||
onSelected: (DropDownChoices choice) {
|
||||
@ -405,7 +405,7 @@ class _FolderViewState extends State<FolderView> {
|
||||
onPressed: _folderViewChooserSelected,
|
||||
key: const ValueKey("FolderViewSelector"),
|
||||
),
|
||||
if (appState.remoteGitRepoConfigured) SyncButton(),
|
||||
if (settings.remoteGitRepoConfigured) SyncButton(),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.search),
|
||||
onPressed: () {
|
||||
|
@ -132,7 +132,8 @@ class _GitRemoteSettingsScreenState extends State<GitRemoteSettingsScreen> {
|
||||
}
|
||||
|
||||
var stateContainer = Provider.of<StateContainer>(context);
|
||||
var gitDir = stateContainer.appState.gitBaseDirectory;
|
||||
final settings = Provider.of<Settings>(context);
|
||||
var gitDir = settings.gitBaseDirectory;
|
||||
|
||||
// Figure out the next available folder
|
||||
String repoFolderName = "journal_";
|
||||
|
@ -18,7 +18,6 @@ import 'package:gitjournal/screens/settings_note_metadata.dart';
|
||||
import 'package:gitjournal/screens/settings_tags.dart';
|
||||
import 'package:gitjournal/screens/settings_widgets.dart';
|
||||
import 'package:gitjournal/settings.dart';
|
||||
import 'package:gitjournal/state_container.dart';
|
||||
import 'package:gitjournal/utils.dart';
|
||||
import 'package:gitjournal/widgets/folder_selection_dialog.dart';
|
||||
import 'package:gitjournal/widgets/pro_overlay.dart';
|
||||
@ -55,10 +54,8 @@ class SettingsListState extends State<SettingsList> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var stateContainer = Provider.of<StateContainer>(context, listen: false);
|
||||
|
||||
var remoteGitConfigured = stateContainer.appState.remoteGitRepoConfigured;
|
||||
var settings = Provider.of<Settings>(context);
|
||||
var remoteGitConfigured = settings.remoteGitRepoConfigured;
|
||||
|
||||
var saveGitAuthor = (String gitAuthor) {
|
||||
settings.gitAuthor = gitAuthor;
|
||||
|
@ -75,6 +75,15 @@ class Settings extends ChangeNotifier {
|
||||
|
||||
Set<String> inlineTagPrefixes = {'#'};
|
||||
|
||||
// From AppState
|
||||
String localGitRepoFolderName = "";
|
||||
bool localGitRepoConfigured = false;
|
||||
|
||||
String remoteGitRepoFolderName = "";
|
||||
bool remoteGitRepoConfigured = false;
|
||||
|
||||
String gitBaseDirectory = "";
|
||||
|
||||
void load(SharedPreferences pref) {
|
||||
onBoardingCompleted = pref.getBool("onBoardingCompleted") ?? false;
|
||||
|
||||
@ -158,6 +167,13 @@ class Settings extends ChangeNotifier {
|
||||
|
||||
inlineTagPrefixes =
|
||||
pref.getStringList("inlineTagPrefixes")?.toSet() ?? inlineTagPrefixes;
|
||||
|
||||
// From AppState
|
||||
localGitRepoConfigured = pref.getBool("localGitRepoConfigured") ?? false;
|
||||
remoteGitRepoConfigured = pref.getBool("remoteGitRepoConfigured") ?? false;
|
||||
localGitRepoFolderName = pref.getString("localGitRepoPath") ?? "";
|
||||
remoteGitRepoFolderName = pref.getString("remoteGitRepoPath") ?? "";
|
||||
gitBaseDirectory = pref.getString("gitBaseDirectory") ?? "";
|
||||
}
|
||||
|
||||
Future save() async {
|
||||
@ -245,6 +261,12 @@ class Settings extends ChangeNotifier {
|
||||
|
||||
pref.setInt("settingsVersion", version);
|
||||
|
||||
pref.setBool("localGitRepoConfigured", localGitRepoConfigured);
|
||||
pref.setBool("remoteGitRepoConfigured", remoteGitRepoConfigured);
|
||||
pref.setString("localGitRepoPath", localGitRepoFolderName);
|
||||
pref.setString("remoteGitRepoPath", remoteGitRepoFolderName);
|
||||
pref.setString("gitBaseDirectory", gitBaseDirectory);
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@ -330,6 +352,11 @@ class Settings extends ChangeNotifier {
|
||||
'swipeToDelete': swipeToDelete.toString(),
|
||||
'inlineTagPrefixes': inlineTagPrefixes.join(' '),
|
||||
'emojiParser': emojiParser.toString(),
|
||||
'localGitRepoConfigured': localGitRepoConfigured.toString(),
|
||||
'remoteGitRepoConfigured': remoteGitRepoConfigured.toString(),
|
||||
'localGitRepoFolderName': localGitRepoFolderName.toString(),
|
||||
'remoteGitRepoFolderName': remoteGitRepoFolderName.toString(),
|
||||
'gitBaseDirectory': gitBaseDirectory.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ import 'package:gitjournal/setup/clone_url.dart';
|
||||
import 'package:gitjournal/setup/loading_error.dart';
|
||||
import 'package:gitjournal/setup/repo_selector.dart';
|
||||
import 'package:gitjournal/setup/sshkey.dart';
|
||||
import 'package:gitjournal/state_container.dart';
|
||||
import 'package:gitjournal/utils.dart';
|
||||
import 'package:gitjournal/utils/logger.dart';
|
||||
|
||||
@ -468,9 +467,8 @@ class GitHostSetupScreenState extends State<GitHostSetupScreen> {
|
||||
gitCloneErrorMessage = "";
|
||||
});
|
||||
|
||||
var stateContainer = Provider.of<StateContainer>(context);
|
||||
var appState = stateContainer.appState;
|
||||
var basePath = appState.gitBaseDirectory;
|
||||
final settings = Provider.of<Settings>(context);
|
||||
var basePath = settings.gitBaseDirectory;
|
||||
|
||||
// Just in case it was half cloned because of an error
|
||||
String repoPath = p.join(basePath, widget.repoFolderName);
|
||||
|
@ -5,7 +5,6 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:synchronized/synchronized.dart';
|
||||
|
||||
import 'package:gitjournal/analytics.dart';
|
||||
@ -23,6 +22,7 @@ import 'package:gitjournal/utils/logger.dart';
|
||||
|
||||
class StateContainer with ChangeNotifier {
|
||||
final AppState appState;
|
||||
final Settings settings;
|
||||
|
||||
final _opLock = Lock();
|
||||
final _loadLock = Lock();
|
||||
@ -33,33 +33,33 @@ class StateContainer with ChangeNotifier {
|
||||
GitNoteRepository _gitRepo;
|
||||
NotesCache _notesCache;
|
||||
|
||||
StateContainer(this.appState) {
|
||||
assert(appState.localGitRepoConfigured);
|
||||
StateContainer(this.appState, this.settings) {
|
||||
assert(settings.localGitRepoConfigured);
|
||||
|
||||
String repoPath;
|
||||
if (appState.remoteGitRepoConfigured) {
|
||||
if (settings.remoteGitRepoConfigured) {
|
||||
repoPath =
|
||||
p.join(appState.gitBaseDirectory, appState.remoteGitRepoFolderName);
|
||||
} else if (appState.localGitRepoConfigured) {
|
||||
p.join(settings.gitBaseDirectory, settings.remoteGitRepoFolderName);
|
||||
} else if (settings.localGitRepoConfigured) {
|
||||
repoPath =
|
||||
p.join(appState.gitBaseDirectory, appState.localGitRepoFolderName);
|
||||
p.join(settings.gitBaseDirectory, settings.localGitRepoFolderName);
|
||||
}
|
||||
|
||||
_gitRepo = GitNoteRepository(gitDirPath: repoPath);
|
||||
appState.notesFolder = NotesFolderFS(null, _gitRepo.gitDirPath);
|
||||
|
||||
// Just a fail safe
|
||||
if (!appState.remoteGitRepoConfigured) {
|
||||
if (!settings.remoteGitRepoConfigured) {
|
||||
removeExistingRemoteClone();
|
||||
}
|
||||
|
||||
// Makes it easier to filter the analytics
|
||||
getAnalytics().firebase.setUserProperty(
|
||||
name: 'onboarded',
|
||||
value: appState.remoteGitRepoConfigured.toString(),
|
||||
value: settings.remoteGitRepoConfigured.toString(),
|
||||
);
|
||||
|
||||
var cachePath = p.join(appState.gitBaseDirectory, "cache.json");
|
||||
var cachePath = p.join(settings.gitBaseDirectory, "cache.json");
|
||||
_notesCache = NotesCache(
|
||||
filePath: cachePath,
|
||||
notesBasePath: _gitRepo.gitDirPath,
|
||||
@ -79,7 +79,7 @@ class StateContainer with ChangeNotifier {
|
||||
|
||||
void removeExistingRemoteClone() async {
|
||||
var remoteGitDir = Directory(
|
||||
p.join(appState.gitBaseDirectory, appState.remoteGitRepoFolderName));
|
||||
p.join(settings.gitBaseDirectory, settings.remoteGitRepoFolderName));
|
||||
var dotGitDir = Directory(p.join(remoteGitDir.path, ".git"));
|
||||
|
||||
bool exists = dotGitDir.existsSync();
|
||||
@ -100,7 +100,7 @@ class StateContainer with ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> syncNotes({bool doNotThrow = false}) async {
|
||||
if (!appState.remoteGitRepoConfigured) {
|
||||
if (!settings.remoteGitRepoConfigured) {
|
||||
Log.d("Not syncing because RemoteRepo not configured");
|
||||
return true;
|
||||
}
|
||||
@ -348,21 +348,21 @@ class StateContainer with ChangeNotifier {
|
||||
|
||||
void completeGitHostSetup(String repoFolderName) {
|
||||
() async {
|
||||
var reconfiguringRemote = appState.remoteGitRepoConfigured;
|
||||
var reconfiguringRemote = settings.remoteGitRepoConfigured;
|
||||
|
||||
appState.remoteGitRepoConfigured = true;
|
||||
appState.remoteGitRepoFolderName = repoFolderName;
|
||||
settings.remoteGitRepoConfigured = true;
|
||||
settings.remoteGitRepoFolderName = repoFolderName;
|
||||
|
||||
if (!reconfiguringRemote) {
|
||||
await migrateGitRepo(
|
||||
fromGitBasePath: appState.localGitRepoFolderName,
|
||||
toGitBaseFolder: appState.remoteGitRepoFolderName,
|
||||
gitBasePath: appState.gitBaseDirectory,
|
||||
fromGitBasePath: settings.localGitRepoFolderName,
|
||||
toGitBaseFolder: settings.remoteGitRepoFolderName,
|
||||
gitBasePath: settings.gitBaseDirectory,
|
||||
);
|
||||
}
|
||||
|
||||
var repoPath =
|
||||
p.join(appState.gitBaseDirectory, appState.remoteGitRepoFolderName);
|
||||
p.join(settings.gitBaseDirectory, settings.remoteGitRepoFolderName);
|
||||
_gitRepo = GitNoteRepository(gitDirPath: repoPath);
|
||||
appState.notesFolder.reset(_gitRepo.gitDirPath);
|
||||
|
||||
@ -376,7 +376,6 @@ class StateContainer with ChangeNotifier {
|
||||
}
|
||||
|
||||
Future _persistConfig() async {
|
||||
var pref = await SharedPreferences.getInstance();
|
||||
await appState.save(pref);
|
||||
await settings.save();
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import 'package:gitjournal/analytics.dart';
|
||||
import 'package:gitjournal/settings.dart';
|
||||
import 'package:gitjournal/state_container.dart';
|
||||
import 'package:gitjournal/utils.dart';
|
||||
import 'package:gitjournal/utils/logger.dart';
|
||||
|
||||
@ -21,11 +20,11 @@ class AppDrawer extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget setupGitButton;
|
||||
var appState = Provider.of<StateContainer>(context).appState;
|
||||
var settings = Provider.of<Settings>(context);
|
||||
var textStyle = Theme.of(context).textTheme.bodyText1;
|
||||
var currentRoute = ModalRoute.of(context).settings.name;
|
||||
|
||||
if (!appState.remoteGitRepoConfigured) {
|
||||
if (!settings.remoteGitRepoConfigured) {
|
||||
setupGitButton = ListTile(
|
||||
leading: Icon(Icons.sync, color: textStyle.color),
|
||||
title: Text(tr('drawer.setup'), style: textStyle),
|
||||
@ -43,7 +42,6 @@ class AppDrawer extends StatelessWidget {
|
||||
}
|
||||
|
||||
var divider = Row(children: <Widget>[const Expanded(child: Divider())]);
|
||||
var settings = Provider.of<Settings>(context);
|
||||
|
||||
return Drawer(
|
||||
child: ListView(
|
||||
|
@ -4,7 +4,6 @@ import 'package:flutter_driver/driver_extension.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
import 'package:gitjournal/app.dart';
|
||||
import 'package:gitjournal/appstate.dart';
|
||||
import 'package:gitjournal/settings.dart';
|
||||
import 'package:gitjournal/utils/datetime.dart';
|
||||
|
||||
@ -19,20 +18,20 @@ void main() async {
|
||||
Settings.instance.load(pref);
|
||||
|
||||
await populateWithData(pref);
|
||||
await JournalApp.main(pref);
|
||||
await JournalApp.main();
|
||||
}
|
||||
|
||||
// Generate lots of notes and folders better screenshots
|
||||
Future<void> populateWithData(SharedPreferences pref) async {
|
||||
var dir = await getApplicationDocumentsDirectory();
|
||||
|
||||
var appState = AppState(pref);
|
||||
appState.gitBaseDirectory = dir.path;
|
||||
appState.localGitRepoConfigured = true;
|
||||
appState.localGitRepoFolderName = "journal_local";
|
||||
appState.save(pref);
|
||||
var settings = Settings.instance;
|
||||
settings.gitBaseDirectory = dir.path;
|
||||
settings.localGitRepoConfigured = true;
|
||||
settings.localGitRepoFolderName = "journal_local";
|
||||
settings.save();
|
||||
|
||||
var repoPath = p.join(dir.path, appState.localGitRepoFolderName);
|
||||
var repoPath = p.join(dir.path, settings.localGitRepoFolderName);
|
||||
await GitRepository.init(repoPath);
|
||||
|
||||
print("Filling fake data in $repoPath");
|
||||
|
Reference in New Issue
Block a user