Implement moving the Git Repo to a folder accessible by other apps

This doesn't seem to move it to the SD card, but it does move it to a
public location. This is an Android specific feature.

Not sure if this is allowed with Android 11

Related to #99
Fixes #154
This commit is contained in:
Vishesh Handa
2020-10-17 12:16:35 +02:00
parent c02af7f156
commit bad1a03812
3 changed files with 52 additions and 9 deletions

View File

@ -3,7 +3,6 @@ import 'package:easy_localization/easy_localization.dart';
class Features { class Features {
static bool alwaysPro = false; static bool alwaysPro = false;
static bool perFolderConfig = false; static bool perFolderConfig = false;
static bool externalStorage = false;
static final all = <Feature>[ static final all = <Feature>[
Feature.basicSearch, Feature.basicSearch,

View File

@ -65,7 +65,8 @@ class SettingsListState extends State<SettingsList> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
var settings = Provider.of<Settings>(context); var settings = Provider.of<Settings>(context);
var appSettings = Provider.of<AppSettings>(context); var appSettings = Provider.of<AppSettings>(context);
final appState = Provider.of<StateContainer>(context).appState; final stateContainer = Provider.of<StateContainer>(context);
final appState = stateContainer.appState;
var saveGitAuthor = (String gitAuthor) { var saveGitAuthor = (String gitAuthor) {
settings.gitAuthor = gitAuthor; settings.gitAuthor = gitAuthor;
@ -289,7 +290,7 @@ class SettingsListState extends State<SettingsList> {
Navigator.of(context).push(route); Navigator.of(context).push(route);
}, },
), ),
if (Platform.isAndroid && Features.externalStorage) if (Platform.isAndroid)
SwitchListTile( SwitchListTile(
title: Text(tr('settings.storage.useLocal')), title: Text(tr('settings.storage.useLocal')),
value: settings.storeInternally, value: settings.storeInternally,
@ -297,6 +298,10 @@ class SettingsListState extends State<SettingsList> {
if (newVal == true) { if (newVal == true) {
settings.storeInternally = true; settings.storeInternally = true;
settings.storageLocation = ""; settings.storageLocation = "";
settings.save();
setState(() {});
stateContainer.moveRepoToPath();
} else { } else {
var req = await Permission.storage.request(); var req = await Permission.storage.request();
if (req.isDenied) { if (req.isDenied) {
@ -305,6 +310,7 @@ class SettingsListState extends State<SettingsList> {
settings.save(); settings.save();
setState(() {}); setState(() {});
stateContainer.moveRepoToPath();
return; return;
} }
settings.storeInternally = true; settings.storeInternally = true;
@ -321,24 +327,24 @@ class SettingsListState extends State<SettingsList> {
if (path == null) { if (path == null) {
settings.storeInternally = false; settings.storeInternally = false;
settings.storageLocation = ""; settings.storageLocation = "";
settings.save(); settings.save();
setState(() {}); setState(() {});
stateContainer.moveRepoToPath();
return; return;
} }
settings.storageLocation = p.join(path, "GitJournal"); settings.storageLocation = p.join(path, "GitJournal");
settings.storeInternally = false; settings.storeInternally = false;
settings.save(); settings.save();
setState(() {}); setState(() {});
stateContainer.moveRepoToPath();
return; return;
} }
settings.save();
setState(() {});
// FIXME: Move the folder to be stored locally!
}, },
), ),
if (Platform.isAndroid && Features.externalStorage) if (Platform.isAndroid)
ListTile( ListTile(
title: Text(tr('settings.storage.repoLocation')), title: Text(tr('settings.storage.repoLocation')),
subtitle: Text(settings.storageLocation), subtitle: Text(settings.storageLocation),

View File

@ -35,13 +35,18 @@ class StateContainer with ChangeNotifier {
GitNoteRepository _gitRepo; GitNoteRepository _gitRepo;
NotesCache _notesCache; NotesCache _notesCache;
String repoPath;
StateContainer({ StateContainer({
@required this.appState, @required this.appState,
@required this.settings, @required this.settings,
@required this.gitBaseDirectory, @required this.gitBaseDirectory,
@required this.cacheDirectory, @required this.cacheDirectory,
}) { }) {
var repoPath = p.join(gitBaseDirectory, settings.internalRepoFolderName); var folderName = settings.internalRepoFolderName;
repoPath = settings.storeInternally
? p.join(gitBaseDirectory, folderName)
: p.join(settings.storageLocation, folderName);
_gitRepo = GitNoteRepository(gitDirPath: repoPath, settings: settings); _gitRepo = GitNoteRepository(gitDirPath: repoPath, settings: settings);
appState.notesFolder = NotesFolderFS(null, _gitRepo.gitDirPath, settings); appState.notesFolder = NotesFolderFS(null, _gitRepo.gitDirPath, settings);
@ -351,4 +356,37 @@ class StateContainer with ChangeNotifier {
Future _persistConfig() async { Future _persistConfig() async {
await settings.save(); await settings.save();
} }
Future<void> moveRepoToPath() async {
var folderName = settings.internalRepoFolderName;
var newRepoPath = settings.storeInternally
? p.join(gitBaseDirectory, folderName)
: p.join(settings.storageLocation, folderName);
if (newRepoPath != repoPath) {
Log.i("Old Path: $repoPath");
Log.i("New Path: $newRepoPath");
await Directory(newRepoPath).create(recursive: true);
await _copyDirectory(repoPath, newRepoPath);
await Directory(repoPath).delete(recursive: true);
repoPath = newRepoPath;
appState.notesFolder.reset(repoPath);
notifyListeners();
}
}
}
Future<void> _copyDirectory(String source, String destination) async {
await for (var entity in Directory(source).list(recursive: false)) {
if (entity is Directory) {
var newDirectory = Directory(p.join(
Directory(destination).absolute.path, p.basename(entity.path)));
await newDirectory.create();
await _copyDirectory(entity.absolute.path, newDirectory.path);
} else if (entity is File) {
await entity.copy(p.join(destination, p.basename(entity.path)));
}
}
} }