preserve notes
This commit is contained in:
parent
6aac11934f
commit
3ed60ca3d8
|
@ -43,3 +43,4 @@ app.*.map.json
|
|||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
*.notes
|
|
@ -13,7 +13,6 @@ class Editor extends StatefulWidget {
|
|||
class _Editor extends State<Editor> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return InputListener(LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||
//print("opening document " + path + " " + startLine.toString());
|
||||
return View();
|
||||
|
|
|
@ -31,6 +31,16 @@ class LineFile extends ChangeNotifier {
|
|||
line += 1;
|
||||
});
|
||||
|
||||
File notesFile = File("$path.subwrite.notes");
|
||||
if (notesFile.existsSync()) {
|
||||
notesFile.readAsLinesSync().forEach((notetext) {
|
||||
var parts = notetext.split(":");
|
||||
var line = int.parse(parts[0]);
|
||||
var note = parts.sublist(1).join(":");
|
||||
addNoteAtLine(line, note);
|
||||
});
|
||||
}
|
||||
|
||||
// handle the empty file case
|
||||
if (backingLines.isEmpty) {
|
||||
backingLines.insert(0, LineInfo(path, 1, ""));
|
||||
|
@ -115,9 +125,17 @@ class LineFile extends ChangeNotifier {
|
|||
|
||||
void saveFile() {
|
||||
String content = '';
|
||||
String notes = '';
|
||||
for (var l in backingLines) {
|
||||
content += '${l.text}\n';
|
||||
for (var annot in l.annotations) {
|
||||
if (annot.description != null) {
|
||||
notes += '${annot.sourceLink.lineStart}:${annot.description}\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File("$path.subwrite.notes").writeAsStringSync(notes);
|
||||
File(path).writeAsStringSync(content);
|
||||
}
|
||||
|
||||
|
@ -379,6 +397,10 @@ class LineFile extends ChangeNotifier {
|
|||
}
|
||||
|
||||
addNote(String note) {
|
||||
addNoteAtLine(cursor.line, note);
|
||||
}
|
||||
|
||||
addNoteAtLine(int line, String note) {
|
||||
var notetype = "note";
|
||||
if (note.startsWith("[incomplete]")) {
|
||||
notetype = "incomplete";
|
||||
|
@ -386,10 +408,10 @@ class LineFile extends ChangeNotifier {
|
|||
notetype = "edit";
|
||||
}
|
||||
|
||||
backingLines[cursor.line - 1].annotations.add(LineAnnotation(
|
||||
backingLines[line - 1].annotations.add(LineAnnotation(
|
||||
SourceLink(
|
||||
path,
|
||||
lineStart: cursor.line,
|
||||
lineStart: line,
|
||||
),
|
||||
"notes",
|
||||
AnnotationType.note,
|
||||
|
|
|
@ -46,7 +46,6 @@ class LineInfo extends ChangeNotifier {
|
|||
|
||||
List<Widget> stackElements = List.empty(growable: true);
|
||||
|
||||
|
||||
var charWidth = (fontSize / 2.0);
|
||||
var lineHeight = (fontSize * 1.2);
|
||||
var usableSize = (constraints.maxWidth - gutterWidth - rightMargin - leftMargin);
|
||||
|
@ -88,16 +87,13 @@ class LineInfo extends ChangeNotifier {
|
|||
var cursorPosTop = (cursorStart! / maxCharsBeforeWrapping).floorToDouble() * lineHeight;
|
||||
var cursorPosLeft = ((cursorStart! % maxCharsBeforeWrapping) * charWidth) - charWidth / 2.0;
|
||||
TextStyle cursorStyle = TextStyle(fontFamily: 'Iosevka', fontSize: fontSize, color: foreground, backgroundColor: Colors.transparent, letterSpacing: -2.0);
|
||||
var cursorPos = Positioned(top: cursorPosTop.toDouble(), left: leftMargin+cursorPosLeft.toDouble(), child: FadeTransition(
|
||||
opacity: animationController, child: Text("|", style: cursorStyle)));
|
||||
stackElements.add( cursorPos);
|
||||
var cursorPos =
|
||||
Positioned(top: cursorPosTop.toDouble(), left: leftMargin + cursorPosLeft.toDouble(), child: FadeTransition(opacity: animationController, child: Text("|", style: cursorStyle)));
|
||||
stackElements.add(cursorPos);
|
||||
}
|
||||
|
||||
|
||||
var cursorOverlay = Stack(children: stackElements);
|
||||
|
||||
|
||||
|
||||
return Listener(
|
||||
onPointerDown: (event) {
|
||||
var inMargin = (event.localPosition.dx - gutterWidth) > usableSize;
|
||||
|
@ -158,7 +154,7 @@ class LineInfo extends ChangeNotifier {
|
|||
margin: EdgeInsets.only(right: 1, top: 0, bottom: 0, left: 0),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Flex(direction: Axis.horizontal, mainAxisAlignment: MainAxisAlignment.start, children: sidebarContent)),
|
||||
cursorOverlay,
|
||||
cursorOverlay,
|
||||
]))));
|
||||
},
|
||||
);
|
||||
|
|
|
@ -11,21 +11,18 @@ import 'line_info.dart';
|
|||
class View extends StatefulWidget {
|
||||
View({Key? key}) : super(key: key);
|
||||
|
||||
|
||||
@override
|
||||
_View createState() => _View();
|
||||
}
|
||||
|
||||
class _View extends State<View> with SingleTickerProviderStateMixin {
|
||||
|
||||
late AnimationController _animationController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_animationController = AnimationController(vsync: this, duration: const Duration(milliseconds: 300));
|
||||
_animationController = AnimationController(vsync: this, duration: const Duration(milliseconds: 300));
|
||||
_animationController.repeat(reverse: true);
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -40,53 +37,47 @@ class _View extends State<View> with SingleTickerProviderStateMixin {
|
|||
|
||||
if (doc.backingLines.isEmpty) {
|
||||
return Center(
|
||||
child: Row (
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: () async {
|
||||
String? result = await FilePicker.platform.saveFile();
|
||||
|
||||
|
||||
ElevatedButton.icon(onPressed: () async {
|
||||
String? result = await FilePicker.platform.saveFile(
|
||||
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
File(result).createSync(recursive: false);
|
||||
doc.openFile(result, 0);
|
||||
doc.focus.requestFocus();
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
|
||||
|
||||
}, icon: Icon(Icons.create, color: foreground), label: const Text("New Document"),
|
||||
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(tabs),
|
||||
foregroundColor: MaterialStateProperty.all(foreground))),
|
||||
|
||||
SizedBox(width: 20,),
|
||||
|
||||
ElevatedButton.icon(onPressed: () async {
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
allowMultiple: false,
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ['md','txt'],
|
||||
);
|
||||
if (result != null) {
|
||||
doc.openFile(result.files.single.path!, 0);
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
|
||||
|
||||
}, icon: Icon(Icons.file_open, color: foreground), label: const Text("Open Document"),
|
||||
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(tabs),
|
||||
foregroundColor: MaterialStateProperty.all(foreground))),
|
||||
|
||||
if (result != null) {
|
||||
File(result).createSync(recursive: false);
|
||||
doc.openFile(result, 0);
|
||||
doc.focus.requestFocus();
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
},
|
||||
icon: Icon(Icons.create, color: foreground),
|
||||
label: const Text("New Document"),
|
||||
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(tabs), foregroundColor: MaterialStateProperty.all(foreground))),
|
||||
SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () async {
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
allowMultiple: false,
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ['md', 'txt'],
|
||||
);
|
||||
if (result != null) {
|
||||
doc.openFile(result.files.single.path!, 0);
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
},
|
||||
icon: Icon(Icons.file_open, color: foreground),
|
||||
label: const Text("Open Document"),
|
||||
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(tabs), foregroundColor: MaterialStateProperty.all(foreground))),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
} else {
|
||||
return ScrollablePositionedList.builder(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
|
@ -98,8 +89,7 @@ class _View extends State<View> with SingleTickerProviderStateMixin {
|
|||
return ChangeNotifierProvider.value(
|
||||
value: doc.backingLines[index],
|
||||
builder: (lcontext, lineinfo) {
|
||||
return Provider.of<LineInfo>(lcontext).build(
|
||||
context, _animationController);
|
||||
return Provider.of<LineInfo>(lcontext).build(context, _animationController);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue