168 lines
5.6 KiB
Dart
168 lines
5.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_code_editor/flutter_code_editor.dart';
|
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
|
import 'package:markdown/markdown.dart' as md;
|
|
import 'package:flutter_markdown_latex/flutter_markdown_latex.dart';
|
|
import 'themes/day.dart';
|
|
import 'themes/night.dart';
|
|
import 'themes/markdown.dart';
|
|
import 'dart:io';
|
|
|
|
class NoteEditorScreen extends StatefulWidget {
|
|
final File note;
|
|
bool isDarkMode;
|
|
|
|
NoteEditorScreen({required this.note, required this.isDarkMode});
|
|
|
|
@override
|
|
_NoteEditorScreenState createState() => _NoteEditorScreenState();
|
|
}
|
|
|
|
class _NoteEditorScreenState extends State<NoteEditorScreen> {
|
|
bool _isPreviewMode = false; // Default: Editing mode
|
|
late CodeController _controller;
|
|
double _fontSize = 16.0; // Default font size
|
|
|
|
void _updateFontSize(double newSize) {
|
|
setState(() {
|
|
_fontSize = newSize;
|
|
});
|
|
}
|
|
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadNoteContent();
|
|
}
|
|
|
|
Future<void> _loadNoteContent() async {
|
|
final content = await widget.note.readAsString();
|
|
setState(() {
|
|
_controller = CodeController(
|
|
text: content,
|
|
language: markdown,
|
|
);
|
|
_controller.addListener(_saveNote);
|
|
_controller.popupController.enabled = false;
|
|
});
|
|
}
|
|
|
|
Future<void> _saveNote() async {
|
|
await widget.note.writeAsString(_controller.text);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.removeListener(_saveNote);
|
|
_controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: Text(widget.note.uri.pathSegments.last.replaceAll('.md', '')),
|
|
actions: [
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 15),
|
|
child: PopupMenuButton<String>(
|
|
icon: Icon(
|
|
Icons.radio_button_checked,
|
|
color: Colors.orange
|
|
),
|
|
onSelected: (String value) {
|
|
if (value == 'Toggle Preview') {
|
|
setState(() {
|
|
_isPreviewMode = !_isPreviewMode;
|
|
});
|
|
}
|
|
},
|
|
itemBuilder: (BuildContext context) => [
|
|
PopupMenuItem<String>(
|
|
value: 'Toggle Preview',
|
|
child: ListTile(
|
|
leading: Icon(_isPreviewMode ? Icons.edit : Icons.preview),
|
|
title: Text(_isPreviewMode ? 'Edit Mode' : 'Preview Mode'),
|
|
),
|
|
),
|
|
PopupMenuItem<String>(
|
|
enabled: false,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Font Size'),
|
|
StatefulBuilder(
|
|
builder: (context, setState) {
|
|
return Slider(
|
|
value: _fontSize,
|
|
min: 12.0,
|
|
max: 24.0,
|
|
divisions: 6,
|
|
label: _fontSize.toString(),
|
|
onChanged: (newSize) {
|
|
setState(() {
|
|
_fontSize = newSize;
|
|
});
|
|
_updateFontSize(newSize);
|
|
},
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
body: _controller == null
|
|
? Center(child: CircularProgressIndicator())
|
|
: _isPreviewMode
|
|
? Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: SingleChildScrollView(
|
|
child: MarkdownBody(
|
|
builders: {
|
|
'latex': LatexElementBuilder(
|
|
textStyle: TextStyle(
|
|
color: widget.isDarkMode ? Colors.white : Colors.black
|
|
)
|
|
),
|
|
},
|
|
extensionSet: md.ExtensionSet(
|
|
[LatexBlockSyntax()],
|
|
[LatexInlineSyntax()],
|
|
),
|
|
data: _controller.text, // ✅ Plain Markdown without syntax highlighting
|
|
selectable: true, // ✅ Allows text selection
|
|
styleSheet: MarkdownStyleSheet(
|
|
p: TextStyle(fontSize: _fontSize, color: widget.isDarkMode ? Colors.white : Colors.black),
|
|
h1: TextStyle(fontSize: _fontSize + 8, color: widget.isDarkMode ? Colors.white : Colors.black, fontWeight: FontWeight.bold),
|
|
h2: TextStyle(fontSize: _fontSize + 6, color: widget.isDarkMode ? Colors.white : Colors.black, fontWeight: FontWeight.bold),
|
|
h3: TextStyle(fontSize: _fontSize + 4, color: widget.isDarkMode ? Colors.white : Colors.black, fontWeight: FontWeight.bold),
|
|
code: TextStyle(fontSize: _fontSize, backgroundColor: Colors.transparent), // ✅ Disables syntax highlighting
|
|
codeblockDecoration: BoxDecoration(color: Colors.transparent), // ✅ Removes background color from code blocks
|
|
),
|
|
),
|
|
),
|
|
)
|
|
: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: CodeTheme(
|
|
data: CodeThemeData(styles: widget.isDarkMode ? nightTheme : dayTheme),
|
|
child: CodeField(
|
|
gutterStyle: GutterStyle.none,
|
|
controller: _controller,
|
|
expands: true,
|
|
textStyle: TextStyle(
|
|
fontSize: _fontSize,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|