mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-28 09:47:35 +08:00
@ -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
|
||||||
|
@ -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 \n";
|
var relativeImagePath = p.relative(absImagePath, from: parent.folderPath);
|
||||||
|
if (!relativeImagePath.startsWith('.')) {
|
||||||
|
relativeImagePath = './$relativeImagePath';
|
||||||
|
}
|
||||||
|
var imageMarkdown = "\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 \n";
|
var relativeImagePath = p.relative(absImagePath, from: parent.folderPath);
|
||||||
|
if (!relativeImagePath.startsWith('.')) {
|
||||||
|
relativeImagePath = './$relativeImagePath';
|
||||||
|
}
|
||||||
|
var imageMarkdown = "\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
|
||||||
|
@ -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;
|
||||||
|
84
lib/screens/settings_images.dart
Normal file
84
lib/screens/settings_images.dart
Normal 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
|
||||||
|
//
|
@ -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(
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user