Skip to content

Commit 3030bb5

Browse files
committed
Update text editor and todo
1 parent 263dbba commit 3030bb5

28 files changed

Lines changed: 295 additions & 190 deletions

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
### TODO
22

3-
- [] Fix flutter article logo image dimension
4-
- [] Allow download as pdf from the markdown widget
5-
- [] Enable firebase analytic
63
- [] Enable file CRUD and upload to git repo with token
74
- [] Support SSL Pinning and export collection API

lib/components/drawer/drawer_view.dart

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,6 @@ class _DrawerViewState extends State<DrawerView> {
6262
}),
6363
),
6464
),
65-
Padding(
66-
padding: const EdgeInsets.all(8.0),
67-
child: IconButton(
68-
onPressed: () {
69-
AppData().appSettings?.delete();
70-
},
71-
icon: Text("Clear Cache"),
72-
),
73-
),
7465
],
7566
),
7667
),

lib/constants/app.constants.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
const String appTitle = "Te Sengthai";
1+
const String appTitle = "SteGlob";
22

3-
final String hiveEditor = "hive_editor";
4-
final String hiveAPIDir = "api_dir";
5-
final String hiveAppSettings = "app_settings";
3+
final String hiveEditorBox = "hive_editor";
4+
final String hiveAPIDirBox = "api_dir";
5+
final String hiveAppSettingsBox = "app_settings";

lib/features/tab_bar_layout_tool_view.dart

Lines changed: 34 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import 'package:sengthaite_blog/features/tool/api/api_util_view.dart';
1414
import 'package:sengthaite_blog/features/tool/api/api_view_desktop.dart';
1515
import 'package:sengthaite_blog/features/tool/api/api_view_mobile.dart';
1616
import 'package:sengthaite_blog/features/tool/camera/camera_view.dart';
17-
import 'package:sengthaite_blog/features/tool/text_editor/text_editor_extension.dart';
1817
import 'package:sengthaite_blog/features/tool/text_editor/text_editor_tool_desktop.dart';
1918
import 'package:sengthaite_blog/features/tool/text_editor/text_editor_tool_mobile.dart';
19+
import 'package:sengthaite_blog/features/tool/text_editor/text_editor_toolbar_view.dart';
2020
import 'package:sengthaite_blog/generated/models/tool_model.dart';
2121
import 'package:sengthaite_blog/shared/app.layout.dart';
2222
import 'tool/api/api_file_manager_view.dart';
@@ -57,88 +57,48 @@ class TabBarLayoutToolView extends TabBarLayoutView {
5757
builder: (context, controller, widget) {
5858
return Row(
5959
children: [
60-
IconButton(
61-
icon: const Icon(Icons.extension),
62-
onPressed: () {
63-
var context = Navigation().tabBarDetailContext;
64-
if (context == null) {
65-
debugPrint(
66-
"Error downloading md requried context not found",
67-
);
68-
return;
60+
ValueListenableBuilder(
61+
valueListenable: AppLayout.layoutType,
62+
builder: (context, value, child) {
63+
// Hide the button show styling sheet if not mobile screen
64+
if (value != AppLayoutType.mobile) {
65+
return Container();
6966
}
70-
showModalBottomSheet(
71-
context: context,
72-
showDragHandle: true,
73-
builder: (context) {
74-
return Padding(
75-
padding: const EdgeInsets.only(
76-
left: 4,
77-
right: 4,
78-
top: 4,
79-
bottom: 8,
80-
),
81-
child: QuillSimpleToolbar(
82-
controller: controller,
83-
config: QuillSimpleToolbarConfig(
84-
toolbarIconAlignment: WrapAlignment.start,
85-
toolbarIconCrossAlignment:
86-
WrapCrossAlignment.start,
87-
),
88-
),
67+
68+
return IconButton(
69+
icon: const Icon(Icons.extension),
70+
onPressed: () {
71+
var context = Navigation().tabBarDetailContext;
72+
if (context == null) {
73+
debugPrint(
74+
"Error downloading md requried context not found",
75+
);
76+
return;
77+
}
78+
showModalBottomSheet(
79+
context: context,
80+
showDragHandle: true,
81+
builder: (context) {
82+
return Padding(
83+
padding: const EdgeInsets.only(
84+
left: 4,
85+
right: 4,
86+
top: 4,
87+
bottom: 8,
88+
),
89+
child: TextEditorToolbarView(
90+
controller: controller,
91+
),
92+
);
93+
},
8994
);
9095
},
9196
);
9297
},
9398
),
94-
DropdownMenu<DocExportType>(
95-
leadingIcon: Icon(Icons.download),
96-
dropdownMenuEntries: [
97-
DropdownMenuEntry(
98-
value: DocExportType.markdown,
99-
label: 'Markdown',
100-
leadingIcon: Icon(MdiIcons.languageMarkdown),
101-
),
102-
DropdownMenuEntry(
103-
value: DocExportType.pdf,
104-
label: 'PDF',
105-
leadingIcon: Icon(MdiIcons.filePdfBox),
106-
),
107-
DropdownMenuEntry(
108-
value: DocExportType.html,
109-
label: 'html',
110-
leadingIcon: Icon(MdiIcons.languageHtml5),
111-
),
112-
],
113-
initialSelection: DocExportType.markdown,
114-
onSelected: (value) {
115-
if (value == null) {
116-
debugPrint("Required doc export type");
117-
return;
118-
}
119-
try {
120-
var context = Navigation().tabBarDetailContext;
121-
if (context == null) return;
122-
switch (value) {
123-
case DocExportType.markdown:
124-
controller.saveMarkdown();
125-
break;
126-
case DocExportType.pdf:
127-
controller.savePDF();
128-
break;
129-
case DocExportType.html:
130-
controller.saveHTML();
131-
break;
132-
}
133-
} catch (error) {
134-
debugPrint("Download error: ${error.toString()}");
135-
}
136-
},
137-
),
13899
],
139100
);
140101
},
141-
child: Container(),
142102
),
143103
],
144104
widgetBuilder: (context) => AppLayout(

lib/features/tool/api/api_file_manager_view.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart
33
import 'package:sengthaite_blog/constants/theme.dart';
44
import 'package:sengthaite_blog/extensions/http_ext.dart';
55
import 'package:sengthaite_blog/extensions/string_ext.dart';
6-
import 'package:sengthaite_blog/shared/file/hivedir.dart';
7-
import 'package:sengthaite_blog/shared/file/hivehelper.dart';
6+
import 'package:sengthaite_blog/shared/data/file/hivedir.dart';
7+
import 'package:sengthaite_blog/shared/data/file/hivehelper.dart';
88

99
import 'api_request_builder.dart';
1010

@@ -316,7 +316,10 @@ class _APIFileCreationWidgetState extends State<APIFileCreationWidget> {
316316
return AlertDialog(
317317
title: Text(
318318
"Create",
319-
style: textTheme.bodyMedium!.copyWith(fontSize: 20, fontWeight: FontWeight.w600),
319+
style: textTheme.bodyMedium!.copyWith(
320+
fontSize: 20,
321+
fontWeight: FontWeight.w600,
322+
),
320323
),
321324
content: Container(
322325
width: 500,
@@ -418,7 +421,9 @@ class _APIFileCreationWidgetState extends State<APIFileCreationWidget> {
418421
},
419422
child: Text(
420423
"Save",
421-
style: textTheme.bodyMedium!.copyWith(fontWeight: FontWeight.w500),
424+
style: textTheme.bodyMedium!.copyWith(
425+
fontWeight: FontWeight.w500,
426+
),
422427
),
423428
),
424429
],

lib/features/tool/api/api_request_builder.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import 'package:sengthaite_blog/extensions/http_ext.dart';
77
import 'package:sengthaite_blog/features/tool/api/api_util_table_data.dart';
88
import 'package:sengthaite_blog/features/tool/api/api_utils/api_util.dart';
99
import 'package:sengthaite_blog/shared/dialog/error_dialog.dart';
10-
import 'package:sengthaite_blog/shared/file/hivedir.dart';
10+
import 'package:sengthaite_blog/shared/data/file/hivedir.dart';
1111
import 'package:uuid/v4.dart';
1212

1313
class HttpRestRequestDatum extends ChangeNotifier {

lib/features/tool/text_editor/text_editor_tool_base.dart

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,63 @@
11
import 'dart:async';
2+
import 'dart:convert';
23
import 'package:flutter/material.dart';
34
import 'package:flutter_quill/flutter_quill.dart';
45
import 'package:hive_ce/hive.dart';
56
import 'package:rxdart/rxdart.dart';
6-
import 'package:sengthaite_blog/constants/app.constants.dart';
7-
import 'package:sengthaite_blog/shared/file/hiveeditor.dart';
7+
import 'package:sengthaite_blog/features/tool/text_editor/text_editor_toolbar_view.dart';
8+
import 'package:sengthaite_blog/shared/app.data.dart';
9+
import 'package:sengthaite_blog/shared/data/file/hiveeditor.dart';
810

911
class TextEditorTool extends StatefulWidget {
10-
const TextEditorTool({super.key, required this.initQuillController});
12+
const TextEditorTool({
13+
super.key,
14+
required this.initQuillController,
15+
this.showBottomToolbar = false,
16+
});
1117

1218
final ValueNotifier<QuillController> initQuillController;
19+
final bool showBottomToolbar;
1320

1421
@override
1522
State<TextEditorTool> createState() => _TextEditorToolState();
1623
}
1724

1825
class _TextEditorToolState extends State<TextEditorTool> {
1926
final _hiveSubject = PublishSubject<Document>();
27+
final hiveEditor = HiveEditor();
2028
QuillController? controller;
2129

22-
Future<Box<HiveEditor>> get _box async =>
23-
await Hive.openBox<HiveEditor>(hiveEditor);
24-
25-
Future<void> saveOnChanged(Document document) async {
26-
final box = await _box;
27-
final hiveEditor = HiveEditor();
28-
box.put("content", hiveEditor);
29-
debugPrint("Saved markdown: ${document.toPlainText()}");
30-
hiveEditor.saveData(document.toDelta());
31-
}
32-
3330
Future<void> loadMarkdown() async {
3431
try {
35-
final box = await _box;
36-
final hiveBox = box.get("content");
37-
if (hiveBox == null) return;
38-
final data = hiveBox.formatDelta(hiveBox.data);
39-
if (data != null) {
40-
var doc = Document.fromDelta(data);
41-
controller = QuillController(
42-
document: doc,
43-
selection: TextSelection.fromPosition(
44-
TextPosition(offset: doc.length > 0 ? doc.length - 1 : 0),
45-
),
46-
);
47-
} else {
48-
controller = QuillController.basic();
32+
if (await AppData().initTextEditorData() == false) {
33+
throw HiveError("initTextEditorData() failed");
34+
}
35+
final box = AppData().textEditor;
36+
if (box != null) {
37+
final data = box.formatDelta();
38+
if (data != null) {
39+
var doc = Document.fromDelta(data);
40+
controller = QuillController(
41+
document: doc,
42+
selection: TextSelection.fromPosition(
43+
TextPosition(offset: doc.length > 0 ? doc.length - 1 : 0),
44+
),
45+
);
46+
}
4947
}
48+
controller ??= QuillController.basic();
5049
widget.initQuillController.value = controller!;
5150
controller!.changes
5251
.debounceTime(const Duration(milliseconds: 100))
53-
.listen((document) async => await saveOnChanged(controller!.document));
52+
.listen((document) async {
53+
var content = '';
54+
var deltaContent = controller?.document;
55+
if (deltaContent != null) {
56+
content = jsonEncode(deltaContent.toDelta().toJson());
57+
}
58+
AppData().textEditor?.data = content;
59+
await AppData().saveEditorContent();
60+
});
5461
} catch (error) {
5562
debugPrint("load markdown: ${error.toString()}");
5663
}
@@ -72,12 +79,23 @@ class _TextEditorToolState extends State<TextEditorTool> {
7279

7380
@override
7481
Widget build(BuildContext context) {
82+
var showBottomToolbar = widget.showBottomToolbar;
7583
return ValueListenableBuilder(
7684
valueListenable: widget.initQuillController,
7785
builder: (context, controller, widget) {
7886
return Column(
7987
children: [
8088
Expanded(child: QuillEditor.basic(controller: controller)),
89+
if (showBottomToolbar)
90+
Padding(
91+
padding: const EdgeInsets.only(
92+
left: 4,
93+
right: 4,
94+
top: 4,
95+
bottom: 8,
96+
),
97+
child: TextEditorToolbarView(controller: controller),
98+
),
8199
],
82100
);
83101
},
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import 'package:sengthaite_blog/features/tool/text_editor/text_editor_tool_base.dart';
22

33
class TextEditorToolDesktop extends TextEditorTool {
4-
const TextEditorToolDesktop({super.key, required super.initQuillController});
4+
const TextEditorToolDesktop({
5+
super.key,
6+
required super.initQuillController,
7+
super.showBottomToolbar = true,
8+
});
59
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_quill/flutter_quill.dart';
3+
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
4+
import 'package:sengthaite_blog/features/tool/text_editor/text_editor_extension.dart';
5+
import 'package:sengthaite_blog/l10n/app_localizations.dart';
6+
7+
class TextEditorToolbarView extends StatelessWidget {
8+
const TextEditorToolbarView({super.key, required this.controller});
9+
10+
final QuillController controller;
11+
12+
@override
13+
Widget build(BuildContext context) {
14+
var localization = AppLocalizations.of(context);
15+
return QuillSimpleToolbar(
16+
controller: controller,
17+
config: QuillSimpleToolbarConfig(
18+
toolbarIconAlignment: WrapAlignment.start,
19+
toolbarIconCrossAlignment: WrapCrossAlignment.start,
20+
customButtons: [
21+
QuillToolbarCustomButtonOptions(
22+
icon: Icon(MdiIcons.languageMarkdown),
23+
tooltip: localization?.save("MD"),
24+
onPressed: () => controller.saveMarkdown(),
25+
),
26+
QuillToolbarCustomButtonOptions(
27+
icon: Icon(MdiIcons.languageHtml5),
28+
tooltip: localization?.save("HTML"),
29+
onPressed: () => controller.saveHTML(),
30+
),
31+
QuillToolbarCustomButtonOptions(
32+
icon: Icon(MdiIcons.filePdfBox),
33+
tooltip: localization?.save("PDF"),
34+
onPressed: () => controller.savePDF(),
35+
),
36+
],
37+
),
38+
);
39+
}
40+
}

lib/hive_registrar.g.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
import 'package:hive_ce/hive.dart';
66
import 'package:sengthaite_blog/shared/data/appsetting.dart';
7-
import 'package:sengthaite_blog/shared/file/hivedir.dart';
8-
import 'package:sengthaite_blog/shared/file/hiveeditor.dart';
7+
import 'package:sengthaite_blog/shared/data/file/hivedir.dart';
8+
import 'package:sengthaite_blog/shared/data/file/hiveeditor.dart';
99

1010
extension HiveRegistrar on HiveInterface {
1111
void registerAdapters() {

0 commit comments

Comments
 (0)