Allow the default Image location to be configured

Fixes #10
This commit is contained in:
Vishesh Handa
2020-05-20 00:25:20 +02:00
parent 1bf91b9292
commit 4c56ddc4df
6 changed files with 156 additions and 8 deletions

View File

@ -21,6 +21,12 @@ settings:
usageStats: Collect Anonymous Usage Statistics usageStats: Collect Anonymous Usage Statistics
debug: Debug App debug: Debug App
debugLog: Look under the hood debugLog: Look under the hood
images:
title: Image Settings
subtitle: Configure how Images are stored
imageLocation: Image Location
currentFolder: Same Folder as Note
customFolder: Custom Folder
editors: editors:
checklist: checklist:
add: Add Item add: Add Item

View File

@ -270,19 +270,50 @@ class Note with NotesNotifier {
} }
Future<void> addImage(File file) async { Future<void> addImage(File file) async {
var imageFileName = p.basename(file.path); var absImagePath = _buildImagePath(file);
var imagePath = p.join(parent.folderPath, imageFileName); await file.copy(absImagePath);
await file.copy(imagePath);
body = "$body\n ![Image](./$imageFileName)\n"; var relativeImagePath = p.relative(absImagePath, from: parent.folderPath);
if (!relativeImagePath.startsWith('.')) {
relativeImagePath = './$relativeImagePath';
}
var imageMarkdown = "![Image]($relativeImagePath)\n";
if (body.isEmpty) {
body = imageMarkdown;
} else {
body = "$body\n$imageMarkdown";
}
} }
Future<void> addImageSync(File file) async { Future<void> addImageSync(File file) async {
var imageFileName = p.basename(file.path); var absImagePath = _buildImagePath(file);
var imagePath = p.join(parent.folderPath, imageFileName); file.copySync(absImagePath);
file.copySync(imagePath);
body = "$body\n ![Image](./$imageFileName)\n"; var relativeImagePath = p.relative(absImagePath, from: parent.folderPath);
if (!relativeImagePath.startsWith('.')) {
relativeImagePath = './$relativeImagePath';
}
var imageMarkdown = "![Image]($relativeImagePath)\n";
if (body.isEmpty) {
body = imageMarkdown;
} else {
body = "$body\n$imageMarkdown";
}
}
String _buildImagePath(File file) {
String baseFolder;
var imageSpec = Settings.instance.imageLocationSpec;
if (imageSpec == '.') {
baseFolder = parent.folderPath;
} else {
baseFolder = parent.rootFolder.getFolderWithSpec(imageSpec).folderPath;
baseFolder ??= parent.folderPath;
}
var imageFileName = p.basename(file.path);
return p.join(baseFolder, imageFileName);
} }
@override @override

View File

@ -399,6 +399,14 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
return null; return null;
} }
NotesFolderFS get rootFolder {
var folder = this;
while (folder.parent != null) {
folder = folder.parent;
}
return folder;
}
Note getNoteWithSpec(String spec) { Note getNoteWithSpec(String spec) {
var parts = spec.split(p.separator); var parts = spec.split(p.separator);
var folder = this; var folder = this;

View File

@ -0,0 +1,84 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gitjournal/settings.dart';
import 'package:gitjournal/screens/settings_widgets.dart';
import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/widgets/folder_selection_dialog.dart';
import 'package:gitjournal/widgets/pro_overlay.dart';
import 'package:provider/provider.dart';
class SettingsImagesScreen extends StatefulWidget {
@override
SettingsImagesScreenState createState() => SettingsImagesScreenState();
}
class SettingsImagesScreenState extends State<SettingsImagesScreen> {
@override
Widget build(BuildContext context) {
var settings = Settings.instance;
var folder = Provider.of<NotesFolderFS>(context)
.getFolderWithSpec(settings.imageLocationSpec);
var sameFolder = tr("settings.images.currentFolder");
var customFolder = tr("settings.images.customFolder");
var body = ListView(children: <Widget>[
ListPreference(
title: tr("settings.images.imageLocation"),
currentOption:
settings.imageLocationSpec == '.' ? sameFolder : customFolder,
options: [sameFolder, customFolder],
onChange: (String publicStr) {
if (publicStr == sameFolder) {
Settings.instance.imageLocationSpec = ".";
} else {
Settings.instance.imageLocationSpec = "";
}
Settings.instance.save();
setState(() {});
},
),
if (settings.imageLocationSpec != '.')
ListTile(
title: Text(customFolder),
subtitle: Text(folder != null ? folder.publicName : "/"),
onTap: () async {
var destFolder = await showDialog<NotesFolderFS>(
context: context,
builder: (context) => FolderSelectionDialog(),
);
Settings.instance.imageLocationSpec =
destFolder != null ? destFolder.pathSpec() : "";
Settings.instance.save();
setState(() {});
},
),
]);
return Scaffold(
appBar: AppBar(
title: Text(tr('settings.images.title')),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.of(context).pop();
},
),
),
body: ProOverlay(child: body),
);
}
}
//
// Options to expose
// - Image Location
// - Note Directory
// - Custom Directory
// Bool use relative path if possible
// - Image FileName
// - Original Name
// - Note FileName + _num
// - Custom Name
//

View File

@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/screens/debug_screen.dart'; import 'package:gitjournal/screens/debug_screen.dart';
import 'package:gitjournal/screens/settings_editors.dart'; import 'package:gitjournal/screens/settings_editors.dart';
import 'package:gitjournal/screens/settings_images.dart';
import 'package:gitjournal/settings.dart'; import 'package:gitjournal/settings.dart';
import 'package:gitjournal/state_container.dart'; import 'package:gitjournal/state_container.dart';
import 'package:gitjournal/utils.dart'; import 'package:gitjournal/utils.dart';
@ -222,6 +223,16 @@ class SettingsListState extends State<SettingsList> {
Navigator.of(context).push(route); Navigator.of(context).push(route);
}, },
), ),
ListTile(
title: Text(tr('settings.images.title')),
subtitle: Text(tr('settings.images.subtitle')),
onTap: () {
var route = MaterialPageRoute(
builder: (context) => SettingsImagesScreen(),
);
Navigator.of(context).push(route);
},
),
const SizedBox(height: 16.0), const SizedBox(height: 16.0),
SettingsHeader(tr('settings.analytics')), SettingsHeader(tr('settings.analytics')),
SwitchListTile( SwitchListTile(

View File

@ -46,6 +46,8 @@ class Settings {
SettingsMarkdownDefaultView markdownDefaultView = SettingsMarkdownDefaultView markdownDefaultView =
SettingsMarkdownDefaultView.Default; SettingsMarkdownDefaultView.Default;
String imageLocationSpec = "."; // . means the same folder
void load(SharedPreferences pref) { void load(SharedPreferences pref) {
gitAuthor = pref.getString("gitAuthor") ?? gitAuthor; gitAuthor = pref.getString("gitAuthor") ?? gitAuthor;
gitAuthorEmail = pref.getString("gitAuthorEmail") ?? gitAuthorEmail; gitAuthorEmail = pref.getString("gitAuthorEmail") ?? gitAuthorEmail;
@ -94,6 +96,9 @@ class Settings {
homeScreen = homeScreen =
SettingsHomeScreen.fromInternalString(pref.getString("homeScreen")); SettingsHomeScreen.fromInternalString(pref.getString("homeScreen"));
imageLocationSpec =
pref.getString("imageLocationSpec") ?? imageLocationSpec;
} }
Future save() async { Future save() async {
@ -148,6 +153,8 @@ class Settings {
_setBool(pref, "proMode", proMode, defaultSet.proMode); _setBool(pref, "proMode", proMode, defaultSet.proMode);
_setString(pref, "homeScreen", homeScreen.toInternalString(), _setString(pref, "homeScreen", homeScreen.toInternalString(),
defaultSet.homeScreen.toInternalString()); defaultSet.homeScreen.toInternalString());
_setString(pref, "imageLocationSpec", imageLocationSpec,
defaultSet.imageLocationSpec);
pref.setInt("settingsVersion", version); pref.setInt("settingsVersion", version);
@ -206,6 +213,7 @@ class Settings {
'pseudoId': pseudoId, 'pseudoId': pseudoId,
'markdownDefaultView': markdownDefaultView.toInternalString(), 'markdownDefaultView': markdownDefaultView.toInternalString(),
'homeScreen': homeScreen.toInternalString(), 'homeScreen': homeScreen.toInternalString(),
'imageLocationSpec': imageLocationSpec,
}; };
} }