mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-28 01:45:55 +08:00
Add very basic Image support [Android only]
This adds a '+' button to the NoteEditor which allows you to add an image from either the Gallery or Take a photo. It then accordingly adds updates markdown. The file is added in the same directory as the note for now. Related to #10
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
|
@ -250,6 +250,14 @@ class Note with NotesNotifier {
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> addImage(File file) async {
|
||||
var imageFileName = p.basename(file.path);
|
||||
var imagePath = p.join(parent.folderPath, imageFileName);
|
||||
await file.copy(imagePath);
|
||||
|
||||
body = "$body\n \n";
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => _filePath.hashCode;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -159,8 +160,9 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
||||
Expanded(child: FocusScope(child: checklistWidget)),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar:
|
||||
buildEditorBottonBar(context, widget, this, checklist.note),
|
||||
bottomNavigationBar: Builder(
|
||||
builder: (context) => buildEditorBottonBar(context, widget, this),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -249,6 +251,17 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addImage(File file) async {
|
||||
var note = getNote();
|
||||
await note.addImage(file);
|
||||
|
||||
setState(() {
|
||||
checklist = Checklist(note);
|
||||
_noteModified = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
typedef TextChangedFunction = void Function(String);
|
||||
|
@ -1,7 +1,12 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gitjournal/core/note.dart';
|
||||
import 'package:gitjournal/error_reporting.dart';
|
||||
import 'package:share/share.dart';
|
||||
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
typedef NoteCallback = void Function(Note);
|
||||
|
||||
abstract class Editor {
|
||||
@ -15,6 +20,7 @@ abstract class Editor {
|
||||
|
||||
abstract class EditorState {
|
||||
Note getNote();
|
||||
Future<void> addImage(File file);
|
||||
}
|
||||
|
||||
enum DropDownChoices { Rename, DiscardChanges, Share }
|
||||
@ -93,27 +99,45 @@ Widget buildEditorBottonBar(
|
||||
BuildContext context,
|
||||
Editor editor,
|
||||
EditorState editorState,
|
||||
Note note,
|
||||
) {
|
||||
var note = editorState.getNote();
|
||||
var folderName = note.parent.pathSpec();
|
||||
if (folderName.isEmpty) {
|
||||
folderName = "Root Folder";
|
||||
}
|
||||
|
||||
var s = Scaffold.of(context);
|
||||
print("s $s");
|
||||
return StickyBottomAppBar(
|
||||
child: BottomAppBar(
|
||||
elevation: 0.0,
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
FlatButton.icon(
|
||||
icon: Icon(Icons.folder),
|
||||
label: Text(folderName),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: () {
|
||||
var note = editorState.getNote();
|
||||
editor.moveNoteToFolderSelected(note);
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (c) => _buildAddBottomSheet(c, editor, editorState),
|
||||
elevation: 0,
|
||||
);
|
||||
},
|
||||
)
|
||||
),
|
||||
Expanded(
|
||||
child: FlatButton.icon(
|
||||
icon: Icon(Icons.folder),
|
||||
label: Text(folderName),
|
||||
onPressed: () {
|
||||
var note = editorState.getNote();
|
||||
editor.moveNoteToFolderSelected(note);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 32.0,
|
||||
width: 32.0,
|
||||
),
|
||||
],
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
@ -133,3 +157,53 @@ class StickyBottomAppBar extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildAddBottomSheet(
|
||||
BuildContext context,
|
||||
Editor editor,
|
||||
EditorState editorState,
|
||||
) {
|
||||
return Container(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
leading: Icon(Icons.camera),
|
||||
title: const Text("Take Photo"),
|
||||
onTap: () async {
|
||||
try {
|
||||
var image = await ImagePicker.pickImage(
|
||||
source: ImageSource.camera,
|
||||
);
|
||||
|
||||
if (image != null) {
|
||||
await editorState.addImage(image);
|
||||
}
|
||||
} catch (e) {
|
||||
reportError(e, StackTrace.current);
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.image),
|
||||
title: const Text("Add Image"),
|
||||
onTap: () async {
|
||||
try {
|
||||
var image = await ImagePicker.pickImage(
|
||||
source: ImageSource.gallery,
|
||||
);
|
||||
|
||||
if (image != null) {
|
||||
await editorState.addImage(image);
|
||||
}
|
||||
} catch (e) {
|
||||
reportError(e, StackTrace.current);
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:gitjournal/core/note.dart';
|
||||
@ -84,7 +85,9 @@ class JournalEditorState extends State<JournalEditor> implements EditorState {
|
||||
return Scaffold(
|
||||
appBar: buildEditorAppBar(widget, this, noteModified: _noteModified),
|
||||
body: editor,
|
||||
bottomNavigationBar: buildEditorBottonBar(context, widget, this, note),
|
||||
bottomNavigationBar: Builder(
|
||||
builder: (context) => buildEditorBottonBar(context, widget, this),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -101,6 +104,15 @@ class JournalEditorState extends State<JournalEditor> implements EditorState {
|
||||
_noteModified = true;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addImage(File file) async {
|
||||
await getNote().addImage(file);
|
||||
setState(() {
|
||||
_textController.text = note.body;
|
||||
_noteModified = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class _NoteBodyEditor extends StatelessWidget {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:gitjournal/core/note.dart';
|
||||
@ -115,7 +116,9 @@ class MarkdownEditorState extends State<MarkdownEditor> implements EditorState {
|
||||
extraButtons: [extraButton],
|
||||
),
|
||||
body: body,
|
||||
bottomNavigationBar: buildEditorBottonBar(context, widget, this, note),
|
||||
bottomNavigationBar: Builder(
|
||||
builder: (context) => buildEditorBottonBar(context, widget, this),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -144,6 +147,15 @@ class MarkdownEditorState extends State<MarkdownEditor> implements EditorState {
|
||||
_noteModified = true;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addImage(File file) async {
|
||||
await getNote().addImage(file);
|
||||
setState(() {
|
||||
_textController.text = note.body;
|
||||
_noteModified = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class _NoteBodyEditor extends StatelessWidget {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:gitjournal/core/note.dart';
|
||||
@ -81,7 +82,9 @@ class RawEditorState extends State<RawEditor> implements EditorState {
|
||||
return Scaffold(
|
||||
appBar: buildEditorAppBar(widget, this, noteModified: _noteModified),
|
||||
body: editor,
|
||||
bottomNavigationBar: buildEditorBottonBar(context, widget, this, note),
|
||||
bottomNavigationBar: Builder(
|
||||
builder: (context) => buildEditorBottonBar(context, widget, this),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -97,6 +100,15 @@ class RawEditorState extends State<RawEditor> implements EditorState {
|
||||
_noteModified = true;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addImage(File file) async {
|
||||
await getNote().addImage(file);
|
||||
setState(() {
|
||||
_textController.text = note.body;
|
||||
_noteModified = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class _NoteEditor extends StatelessWidget {
|
||||
|
23
pubspec.lock
23
pubspec.lock
@ -258,6 +258,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.2"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.7"
|
||||
flutter_runtime_env:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -373,6 +380,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
image_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: image_picker
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.6+1"
|
||||
image_picker_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -568,7 +589,7 @@ packages:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -51,6 +51,7 @@ dependencies:
|
||||
isolate: ^2.0.3
|
||||
flutter_webview_plugin:
|
||||
git: https://github.com/breez/flutter_webview_plugin.git
|
||||
image_picker: ^0.6.6+1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_launcher_icons: "^0.7.2"
|
||||
|
Reference in New Issue
Block a user