UI changes dashboard
This commit is contained in:
commit
154f18a59b
@ -1,8 +1,19 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="frontend"
|
android:label="frontend"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true" >
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/file_paths" />
|
||||||
|
</provider>
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
@ -30,6 +41,8 @@
|
|||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
|
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
<!-- Required to query activities that can process text, see:
|
<!-- Required to query activities that can process text, see:
|
||||||
https://developer.android.com/training/package-visibility and
|
https://developer.android.com/training/package-visibility and
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
<!-- Show a splash screen on the activity. Automatically removed when
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
the Flutter engine draws its first frame -->
|
the Flutter engine draws its first frame -->
|
||||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
This theme determines the color of the Android Window while your
|
This theme determines the color of the Android Window while your
|
||||||
@ -15,4 +16,7 @@
|
|||||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
<item name="android:windowBackground">?android:colorBackground</item>
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
</style>
|
</style>
|
||||||
|
<paths>
|
||||||
|
<cache-path name="cache" path="." />
|
||||||
|
</paths>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
6
android/app/src/main/res/xml/file_paths.xml
Normal file
6
android/app/src/main/res/xml/file_paths.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<cache-path name="cache" path="." />
|
||||||
|
<external-path name="external" path="." />
|
||||||
|
<!-- You can add more paths as needed -->
|
||||||
|
</paths>
|
||||||
244
lib/Screens/myTemplates/src/tst
Normal file
244
lib/Screens/myTemplates/src/tst
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io' as io show Directory, File;
|
||||||
|
import 'package:flutter_quill/flutter_quill.dart' hide Text;
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_quill/flutter_quill.dart' hide Text;
|
||||||
|
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_quill/flutter_quill.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
import 'package:flutter_quill/flutter_quill_internal.dart';
|
||||||
|
import 'package:flutter_quill/quill_delta.dart';
|
||||||
|
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
|
||||||
|
import 'package:frontend/Screens/myTemplates/quill_delta_sample.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:responsive_builder/responsive_builder.dart';
|
||||||
|
|
||||||
|
import '../../routes/custom_appBar.dart';
|
||||||
|
import '../../routes/custom_drawer.dart';
|
||||||
|
import '../../services/apiService.dart';
|
||||||
|
import '../../utils/auth_utils.dart';
|
||||||
|
import '../../widgets/custom_user_travel.dart';
|
||||||
|
|
||||||
|
class Template extends StatefulWidget {
|
||||||
|
final Map<String, dynamic>? templateData;
|
||||||
|
|
||||||
|
const Template({super.key, required this.templateData});
|
||||||
|
|
||||||
|
static Template fromState(GoRouterState state) {
|
||||||
|
return Template(templateData: state.extra as Map<String, dynamic>?);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
TemplateState createState() => TemplateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TemplateState extends State<Template> {
|
||||||
|
final ApiService apiService = ApiService();
|
||||||
|
|
||||||
|
// final QuillController _controller = QuillController.basic();
|
||||||
|
Color layoutColor = Colors.redAccent;
|
||||||
|
Color bodyColor = Colors.white;
|
||||||
|
final Map<String, TextEditingController> controllers = {};
|
||||||
|
List<String> dataHeader = ["subject"];
|
||||||
|
|
||||||
|
Map<String, dynamic> get TemplateData {
|
||||||
|
final data = {
|
||||||
|
// "org_id": orgId;
|
||||||
|
"template_name": controllers["templateName"]?.text,
|
||||||
|
"subject": controllers["subject"]?.text,
|
||||||
|
"body_html": controllers["bodyData"]?.text,
|
||||||
|
"placeholder": [],
|
||||||
|
// "created_by": userId
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only add group_id if it's an edit operation
|
||||||
|
// if (widget.templateData != null && widget.templateData!.containsKey('group_id')) {
|
||||||
|
// data["template_id"] = templateData;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
for (var field in dataHeader) {
|
||||||
|
controllers[field] = TextEditingController();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateData();
|
||||||
|
|
||||||
|
loadInitialData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
// void dispose() {
|
||||||
|
// // controllers.dispose();
|
||||||
|
// // _editorScrollController.dispose();
|
||||||
|
// _editorFocusNode.dispose();
|
||||||
|
// super.dispose();
|
||||||
|
// }
|
||||||
|
|
||||||
|
void loadInitialData() async {
|
||||||
|
String? layoutString = await getLayoutColor();
|
||||||
|
String? bodyStringColor = await getBodyColor();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
layoutColor = layoutString != null
|
||||||
|
? Color(int.parse(layoutString))
|
||||||
|
: Colors.redAccent;
|
||||||
|
|
||||||
|
bodyColor = bodyStringColor != null
|
||||||
|
? Color(int.parse(bodyStringColor))
|
||||||
|
: Colors.white;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateData() async {
|
||||||
|
// Ensure apiselectedUser is not null before printing
|
||||||
|
if (widget.templateData != null) {
|
||||||
|
print("API Selected User Has Data - ${widget.templateData}");
|
||||||
|
print(
|
||||||
|
"API Selected User Has - ${widget.templateData?["templateData"]?["subject"]}");
|
||||||
|
setState(() {
|
||||||
|
// ✅ Wrap in setState to update the UI
|
||||||
|
controllers["subject"]?.text =
|
||||||
|
widget.templateData?["templateData"]?["subject"] ?? "";
|
||||||
|
|
||||||
|
// if (widget.group?["international_policy_id"] != null) {
|
||||||
|
// selectedInternational =
|
||||||
|
// widget.group!["international_policy_id"].toString();
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
print("API Selected User Has Data - No data available yet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ResponsiveBuilder(builder: (context, sizingInfo) {
|
||||||
|
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFf5f5f5),
|
||||||
|
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||||
|
drawer: CustomDrawer(isDesktop: false),
|
||||||
|
body: Padding(
|
||||||
|
padding: isDesktop
|
||||||
|
? EdgeInsets.symmetric(
|
||||||
|
horizontal: MediaQuery.of(context).size.width *
|
||||||
|
0.1, // 30% of screen width as horizontal padding
|
||||||
|
vertical: MediaQuery.of(context).size.height *
|
||||||
|
0, // 5% of screen height as vertical padding
|
||||||
|
)
|
||||||
|
: EdgeInsets.all(0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
// if (isDesktop) CustomDrawer(isDesktop: true),
|
||||||
|
Expanded(
|
||||||
|
child: buildUserTable(
|
||||||
|
isDesktop, context, bodyColor, layoutColor)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildUserTable(
|
||||||
|
bool isDesktop, context, Color? bodyColor, Color layoutColor) {
|
||||||
|
return Container(
|
||||||
|
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
|
||||||
|
),
|
||||||
|
child: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Editor"),
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
buildTempalteSubject(isDesktop),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.output),
|
||||||
|
tooltip: 'Print Delta JSON to log',
|
||||||
|
onPressed: () {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'The JSON Delta has been printed to the console.')));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
buildTempalteBody(isDesktop)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildTempalteSubject(bool isDesktop) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Subject",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12, fontWeight: FontWeight.w400, color: Colors.black),
|
||||||
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
CustomTextFieldUserTravellerWrapper(
|
||||||
|
isFocused: false,
|
||||||
|
isDesktop: isDesktop,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: TextField(
|
||||||
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
|
controller: controllers["subject"],
|
||||||
|
onChanged: (value) {
|
||||||
|
// _clearError("local_id_num");
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "enter the subject",
|
||||||
|
labelStyle:
|
||||||
|
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildTempalteBody(bool isDesktop) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Content",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
482
lib/Screens/myTemplates/tem
Normal file
482
lib/Screens/myTemplates/tem
Normal file
@ -0,0 +1,482 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io' as io show Directory, File;
|
||||||
|
import 'package:flutter_quill/flutter_quill.dart' hide Text;
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_quill/flutter_quill.dart' hide Text;
|
||||||
|
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_quill/flutter_quill.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
import 'package:flutter_quill/flutter_quill_internal.dart';
|
||||||
|
import 'package:flutter_quill/quill_delta.dart';
|
||||||
|
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
|
||||||
|
import 'package:frontend/Screens/myTemplates/quill_delta_sample.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:responsive_builder/responsive_builder.dart';
|
||||||
|
|
||||||
|
import '../../routes/custom_appBar.dart';
|
||||||
|
import '../../routes/custom_drawer.dart';
|
||||||
|
import '../../services/apiService.dart';
|
||||||
|
import '../../utils/auth_utils.dart';
|
||||||
|
import '../../widgets/custom_user_travel.dart';
|
||||||
|
|
||||||
|
class Template extends StatefulWidget {
|
||||||
|
final Map<String, dynamic>? templateData;
|
||||||
|
|
||||||
|
const Template({super.key, required this.templateData});
|
||||||
|
|
||||||
|
static Template fromState(GoRouterState state) {
|
||||||
|
return Template(templateData: state.extra as Map<String, dynamic>?);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
TemplateState createState() => TemplateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TemplateState extends State<Template> {
|
||||||
|
final ApiService apiService = ApiService();
|
||||||
|
final QuillController _controller = () {
|
||||||
|
return QuillController.basic(
|
||||||
|
config: QuillControllerConfig(
|
||||||
|
clipboardConfig: QuillClipboardConfig(
|
||||||
|
enableExternalRichPaste: true,
|
||||||
|
onImagePaste: (imageBytes) async {
|
||||||
|
if (kIsWeb) {
|
||||||
|
// Dart IO is unsupported on the web.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Save the image somewhere and return the image URL that will be
|
||||||
|
// stored in the Quill Delta JSON (the document).
|
||||||
|
final newFileName =
|
||||||
|
'image-file-${DateTime.now().toIso8601String()}.png';
|
||||||
|
final newPath = path.join(
|
||||||
|
io.Directory.systemTemp.path,
|
||||||
|
newFileName,
|
||||||
|
);
|
||||||
|
final file = await io.File(
|
||||||
|
newPath,
|
||||||
|
).writeAsBytes(imageBytes, flush: true);
|
||||||
|
return file.path;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}();
|
||||||
|
final FocusNode _editorFocusNode = FocusNode();
|
||||||
|
final ScrollController _editorScrollController = ScrollController();
|
||||||
|
// final QuillController _controller = QuillController.basic();
|
||||||
|
Color layoutColor = Colors.redAccent;
|
||||||
|
Color bodyColor = Colors.white;
|
||||||
|
final Map<String, TextEditingController> controllers = {};
|
||||||
|
List<String> dataHeader = ["subject"];
|
||||||
|
|
||||||
|
Map<String, dynamic> get TemplateData {
|
||||||
|
final data = {
|
||||||
|
// "org_id": orgId;
|
||||||
|
"template_name": controllers["templateName"]?.text,
|
||||||
|
"subject": controllers["subject"]?.text,
|
||||||
|
"body_html": controllers["bodyData"]?.text,
|
||||||
|
"placeholder": [],
|
||||||
|
// "created_by": userId
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only add group_id if it's an edit operation
|
||||||
|
// if (widget.templateData != null && widget.templateData!.containsKey('group_id')) {
|
||||||
|
// data["template_id"] = templateData;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
for (var field in dataHeader) {
|
||||||
|
controllers[field] = TextEditingController();
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_editorFocusNode.requestFocus(); // ✅ Ensure focus is requested
|
||||||
|
});
|
||||||
|
_controller.document = Document.fromJson(kQuillDefaultSample);
|
||||||
|
// _controller.document = Document.fromJson(kQuillDefaultSample);
|
||||||
|
// _controller.document = Document.fromJson();
|
||||||
|
// _controller.document.toPlainText();
|
||||||
|
// _controller.readOnly = false;
|
||||||
|
updateData();
|
||||||
|
|
||||||
|
loadInitialData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
// void dispose() {
|
||||||
|
// // controllers.dispose();
|
||||||
|
// // _editorScrollController.dispose();
|
||||||
|
// _editorFocusNode.dispose();
|
||||||
|
// super.dispose();
|
||||||
|
// }
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
_editorScrollController.dispose();
|
||||||
|
_editorFocusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadInitialData() async {
|
||||||
|
String? layoutString = await getLayoutColor();
|
||||||
|
String? bodyStringColor = await getBodyColor();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
layoutColor = layoutString != null
|
||||||
|
? Color(int.parse(layoutString))
|
||||||
|
: Colors.redAccent;
|
||||||
|
|
||||||
|
bodyColor = bodyStringColor != null
|
||||||
|
? Color(int.parse(bodyStringColor))
|
||||||
|
: Colors.white;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateData() async {
|
||||||
|
// Ensure apiselectedUser is not null before printing
|
||||||
|
if (widget.templateData != null) {
|
||||||
|
print("API Selected User Has Data - ${widget.templateData}");
|
||||||
|
print(
|
||||||
|
"API Selected User Has - ${widget.templateData?["templateData"]?["subject"]}");
|
||||||
|
setState(() {
|
||||||
|
// ✅ Wrap in setState to update the UI
|
||||||
|
controllers["subject"]?.text =
|
||||||
|
widget.templateData?["templateData"]?["subject"] ?? "";
|
||||||
|
|
||||||
|
// if (widget.group?["international_policy_id"] != null) {
|
||||||
|
// selectedInternational =
|
||||||
|
// widget.group!["international_policy_id"].toString();
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
print("API Selected User Has Data - No data available yet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ResponsiveBuilder(builder: (context, sizingInfo) {
|
||||||
|
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFf5f5f5),
|
||||||
|
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||||
|
drawer: CustomDrawer(isDesktop: false),
|
||||||
|
body: Padding(
|
||||||
|
padding: isDesktop
|
||||||
|
? EdgeInsets.symmetric(
|
||||||
|
horizontal: MediaQuery.of(context).size.width *
|
||||||
|
0.1, // 30% of screen width as horizontal padding
|
||||||
|
vertical: MediaQuery.of(context).size.height *
|
||||||
|
0, // 5% of screen height as vertical padding
|
||||||
|
)
|
||||||
|
: EdgeInsets.all(0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
// if (isDesktop) CustomDrawer(isDesktop: true),
|
||||||
|
Expanded(
|
||||||
|
child: buildUserTable(
|
||||||
|
isDesktop, context, bodyColor, layoutColor)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildUserTable(
|
||||||
|
bool isDesktop, context, Color? bodyColor, Color layoutColor) {
|
||||||
|
return Container(
|
||||||
|
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
|
||||||
|
),
|
||||||
|
child: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Editor"),
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
buildTempalteSubject(isDesktop),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.output),
|
||||||
|
tooltip: 'Print Delta JSON to log',
|
||||||
|
onPressed: () {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'The JSON Delta has been printed to the console.')));
|
||||||
|
debugPrint(jsonEncode(_controller.document.toDelta().toJson()));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
buildTempalteBody(isDesktop)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildTempalteSubject(bool isDesktop) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Subject",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12, fontWeight: FontWeight.w400, color: Colors.black),
|
||||||
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
CustomTextFieldUserTravellerWrapper(
|
||||||
|
isFocused: false,
|
||||||
|
isDesktop: isDesktop,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: TextField(
|
||||||
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
|
controller: controllers["subject"],
|
||||||
|
onChanged: (value) {
|
||||||
|
// _clearError("local_id_num");
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "enter the subject",
|
||||||
|
labelStyle:
|
||||||
|
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildTempalteBody(bool isDesktop) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Content",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
|
||||||
|
// Expanded(
|
||||||
|
//
|
||||||
|
// child: QuillEditor(
|
||||||
|
// focusNode: _editorFocusNode,
|
||||||
|
// scrollController: _editorScrollController,
|
||||||
|
// controller: _controller,
|
||||||
|
// config: QuillEditorConfig(
|
||||||
|
// placeholder: 'Start writing your notes...',
|
||||||
|
// padding: const EdgeInsets.all(16),
|
||||||
|
// embedBuilders: [
|
||||||
|
// ...FlutterQuillEmbeds.editorBuilders(
|
||||||
|
// imageEmbedConfig: QuillEditorImageEmbedConfig(
|
||||||
|
// imageProviderBuilder: (context, imageUrl) {
|
||||||
|
// // https://pub.dev/packages/flutter_quill_extensions#-image-assets
|
||||||
|
// if (imageUrl.startsWith('assets/')) {
|
||||||
|
// return AssetImage(imageUrl);
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// videoEmbedConfig: QuillEditorVideoEmbedConfig(
|
||||||
|
// customVideoBuilder: (videoUrl, readOnly) {
|
||||||
|
// // To load YouTube videos https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.0
|
||||||
|
// return null;
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// TimeStampEmbedBuilder(),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
|
||||||
|
// ✅ Modern toolbar
|
||||||
|
QuillSimpleToolbar(
|
||||||
|
controller: _controller,
|
||||||
|
config: QuillSimpleToolbarConfig(
|
||||||
|
embedButtons: FlutterQuillEmbeds.toolbarButtons(),
|
||||||
|
showClipboardPaste: true,
|
||||||
|
customButtons: [
|
||||||
|
QuillToolbarCustomButtonOptions(
|
||||||
|
icon: const Icon(Icons.add_alarm_rounded),
|
||||||
|
onPressed: () {
|
||||||
|
_controller.document.insert(
|
||||||
|
_controller.selection.extentOffset,
|
||||||
|
TimeStampEmbed(
|
||||||
|
DateTime.now().toString(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_controller.readOnly = true;
|
||||||
|
_controller.updateSelection(
|
||||||
|
TextSelection.collapsed(
|
||||||
|
offset: _controller.selection.extentOffset + 1,
|
||||||
|
),
|
||||||
|
ChangeSource.local,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
buttonOptions: QuillSimpleToolbarButtonOptions(
|
||||||
|
base: QuillToolbarBaseButtonOptions(
|
||||||
|
afterButtonPressed: () {
|
||||||
|
final isDesktop = {
|
||||||
|
TargetPlatform.linux,
|
||||||
|
TargetPlatform.windows,
|
||||||
|
TargetPlatform.macOS
|
||||||
|
}.contains(defaultTargetPlatform);
|
||||||
|
if (isDesktop) {
|
||||||
|
_editorFocusNode.requestFocus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
linkStyle: QuillToolbarLinkStyleButtonOptions(
|
||||||
|
validateLink: (link) {
|
||||||
|
// Treats all links as valid. When launching the URL,
|
||||||
|
// `https://` is prefixed if the link is incomplete (e.g., `google.com` → `https://google.com`)
|
||||||
|
// however this happens only within the editor.
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
|
||||||
|
// // ✅ Modern editor
|
||||||
|
Container(
|
||||||
|
height: 200,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: Colors.grey),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: QuillEditor(
|
||||||
|
focusNode: _editorFocusNode,
|
||||||
|
scrollController: _editorScrollController,
|
||||||
|
controller: _controller,
|
||||||
|
config: QuillEditorConfig(
|
||||||
|
placeholder: 'Start writing your notes...',
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
embedBuilders: [
|
||||||
|
...FlutterQuillEmbeds.editorBuilders(
|
||||||
|
imageEmbedConfig: QuillEditorImageEmbedConfig(
|
||||||
|
imageProviderBuilder: (context, imageUrl) {
|
||||||
|
// https://pub.dev/packages/flutter_quill_extensions#-image-assets
|
||||||
|
if (imageUrl.startsWith('assets/')) {
|
||||||
|
return AssetImage(imageUrl);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
videoEmbedConfig: QuillEditorVideoEmbedConfig(
|
||||||
|
customVideoBuilder: (videoUrl, readOnly) {
|
||||||
|
// To load YouTube videos https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.0
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TimeStampEmbedBuilder(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// child: QuillEditor.basic(
|
||||||
|
// focusNode: _editorFocusNode,
|
||||||
|
// scrollController: _editorScrollController,
|
||||||
|
// controller: _controller,
|
||||||
|
// // readOnly: true,
|
||||||
|
// config: QuillEditorConfig(
|
||||||
|
// requestKeyboardFocusOnCheckListChanged: false,
|
||||||
|
// // readOnlyMouseCursor: SystemMouseCursors.text,
|
||||||
|
// enableScribble: true,
|
||||||
|
// // readOnly: false,
|
||||||
|
// padding: const EdgeInsets.all(8),
|
||||||
|
// placeholder: 'Type something...',
|
||||||
|
// embedBuilders: [
|
||||||
|
// ...FlutterQuillEmbeds.editorBuilders(
|
||||||
|
// imageEmbedConfig: QuillEditorImageEmbedConfig(
|
||||||
|
// imageProviderBuilder: (context, imageUrl) {
|
||||||
|
// // https://pub.dev/packages/flutter_quill_extensions#-image-assets
|
||||||
|
// if (imageUrl.startsWith('assets/')) {
|
||||||
|
// return AssetImage(imageUrl);
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// videoEmbedConfig: QuillEditorVideoEmbedConfig(
|
||||||
|
// customVideoBuilder: (videoUrl, readOnly) {
|
||||||
|
// // To load YouTube videos https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.0
|
||||||
|
// return null;
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// TimeStampEmbedBuilder(),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeStampEmbed extends Embeddable {
|
||||||
|
const TimeStampEmbed(
|
||||||
|
String value,
|
||||||
|
) : super(timeStampType, value);
|
||||||
|
|
||||||
|
static const String timeStampType = 'timeStamp';
|
||||||
|
|
||||||
|
static TimeStampEmbed fromDocument(Document document) =>
|
||||||
|
TimeStampEmbed(jsonEncode(document.toDelta().toJson()));
|
||||||
|
|
||||||
|
Document get document => Document.fromJson(jsonDecode(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeStampEmbedBuilder extends EmbedBuilder {
|
||||||
|
@override
|
||||||
|
String get key => 'timeStamp';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toPlainText(Embed node) {
|
||||||
|
return node.value.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(
|
||||||
|
BuildContext context,
|
||||||
|
EmbedContext embedContext,
|
||||||
|
) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.access_time_rounded),
|
||||||
|
Text(embedContext.node.value.data as String),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -39,34 +39,7 @@ class Template extends StatefulWidget {
|
|||||||
|
|
||||||
class TemplateState extends State<Template> {
|
class TemplateState extends State<Template> {
|
||||||
final ApiService apiService = ApiService();
|
final ApiService apiService = ApiService();
|
||||||
final QuillController _controller = () {
|
|
||||||
return QuillController.basic(
|
|
||||||
config: QuillControllerConfig(
|
|
||||||
clipboardConfig: QuillClipboardConfig(
|
|
||||||
enableExternalRichPaste: true,
|
|
||||||
onImagePaste: (imageBytes) async {
|
|
||||||
if (kIsWeb) {
|
|
||||||
// Dart IO is unsupported on the web.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Save the image somewhere and return the image URL that will be
|
|
||||||
// stored in the Quill Delta JSON (the document).
|
|
||||||
final newFileName =
|
|
||||||
'image-file-${DateTime.now().toIso8601String()}.png';
|
|
||||||
final newPath = path.join(
|
|
||||||
io.Directory.systemTemp.path,
|
|
||||||
newFileName,
|
|
||||||
);
|
|
||||||
final file = await io.File(
|
|
||||||
newPath,
|
|
||||||
).writeAsBytes(imageBytes, flush: true);
|
|
||||||
return file.path;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}();
|
|
||||||
final FocusNode _editorFocusNode = FocusNode();
|
|
||||||
final ScrollController _editorScrollController = ScrollController();
|
|
||||||
// final QuillController _controller = QuillController.basic();
|
// final QuillController _controller = QuillController.basic();
|
||||||
Color layoutColor = Colors.redAccent;
|
Color layoutColor = Colors.redAccent;
|
||||||
Color bodyColor = Colors.white;
|
Color bodyColor = Colors.white;
|
||||||
@ -99,14 +72,6 @@ class TemplateState extends State<Template> {
|
|||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
_editorFocusNode.requestFocus(); // ✅ Ensure focus is requested
|
|
||||||
});
|
|
||||||
_controller.document = Document.fromJson(kQuillDefaultSample);
|
|
||||||
// _controller.document = Document.fromJson(kQuillDefaultSample);
|
|
||||||
// _controller.document = Document.fromJson();
|
|
||||||
// _controller.document.toPlainText();
|
|
||||||
// _controller.readOnly = false;
|
|
||||||
updateData();
|
updateData();
|
||||||
|
|
||||||
loadInitialData();
|
loadInitialData();
|
||||||
@ -120,13 +85,6 @@ class TemplateState extends State<Template> {
|
|||||||
// super.dispose();
|
// super.dispose();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
void dispose() {
|
|
||||||
_controller.dispose();
|
|
||||||
_editorScrollController.dispose();
|
|
||||||
_editorFocusNode.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadInitialData() async {
|
void loadInitialData() async {
|
||||||
String? layoutString = await getLayoutColor();
|
String? layoutString = await getLayoutColor();
|
||||||
String? bodyStringColor = await getBodyColor();
|
String? bodyStringColor = await getBodyColor();
|
||||||
@ -219,7 +177,6 @@ class TemplateState extends State<Template> {
|
|||||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
'The JSON Delta has been printed to the console.')));
|
'The JSON Delta has been printed to the console.')));
|
||||||
debugPrint(jsonEncode(_controller.document.toDelta().toJson()));
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
@ -280,202 +237,7 @@ class TemplateState extends State<Template> {
|
|||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
|
|
||||||
// Expanded(
|
|
||||||
//
|
|
||||||
// child: QuillEditor(
|
|
||||||
// focusNode: _editorFocusNode,
|
|
||||||
// scrollController: _editorScrollController,
|
|
||||||
// controller: _controller,
|
|
||||||
// config: QuillEditorConfig(
|
|
||||||
// placeholder: 'Start writing your notes...',
|
|
||||||
// padding: const EdgeInsets.all(16),
|
|
||||||
// embedBuilders: [
|
|
||||||
// ...FlutterQuillEmbeds.editorBuilders(
|
|
||||||
// imageEmbedConfig: QuillEditorImageEmbedConfig(
|
|
||||||
// imageProviderBuilder: (context, imageUrl) {
|
|
||||||
// // https://pub.dev/packages/flutter_quill_extensions#-image-assets
|
|
||||||
// if (imageUrl.startsWith('assets/')) {
|
|
||||||
// return AssetImage(imageUrl);
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// videoEmbedConfig: QuillEditorVideoEmbedConfig(
|
|
||||||
// customVideoBuilder: (videoUrl, readOnly) {
|
|
||||||
// // To load YouTube videos https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.0
|
|
||||||
// return null;
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// TimeStampEmbedBuilder(),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
|
|
||||||
// ✅ Modern toolbar
|
|
||||||
QuillSimpleToolbar(
|
|
||||||
controller: _controller,
|
|
||||||
config: QuillSimpleToolbarConfig(
|
|
||||||
embedButtons: FlutterQuillEmbeds.toolbarButtons(),
|
|
||||||
showClipboardPaste: true,
|
|
||||||
customButtons: [
|
|
||||||
QuillToolbarCustomButtonOptions(
|
|
||||||
icon: const Icon(Icons.add_alarm_rounded),
|
|
||||||
onPressed: () {
|
|
||||||
_controller.document.insert(
|
|
||||||
_controller.selection.extentOffset,
|
|
||||||
TimeStampEmbed(
|
|
||||||
DateTime.now().toString(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
_controller.readOnly = true;
|
|
||||||
_controller.updateSelection(
|
|
||||||
TextSelection.collapsed(
|
|
||||||
offset: _controller.selection.extentOffset + 1,
|
|
||||||
),
|
|
||||||
ChangeSource.local,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
buttonOptions: QuillSimpleToolbarButtonOptions(
|
|
||||||
base: QuillToolbarBaseButtonOptions(
|
|
||||||
afterButtonPressed: () {
|
|
||||||
final isDesktop = {
|
|
||||||
TargetPlatform.linux,
|
|
||||||
TargetPlatform.windows,
|
|
||||||
TargetPlatform.macOS
|
|
||||||
}.contains(defaultTargetPlatform);
|
|
||||||
if (isDesktop) {
|
|
||||||
_editorFocusNode.requestFocus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
linkStyle: QuillToolbarLinkStyleButtonOptions(
|
|
||||||
validateLink: (link) {
|
|
||||||
// Treats all links as valid. When launching the URL,
|
|
||||||
// `https://` is prefixed if the link is incomplete (e.g., `google.com` → `https://google.com`)
|
|
||||||
// however this happens only within the editor.
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
|
|
||||||
// // ✅ Modern editor
|
|
||||||
Container(
|
|
||||||
height: 200,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border.all(color: Colors.grey),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
child: QuillEditor(
|
|
||||||
focusNode: _editorFocusNode,
|
|
||||||
scrollController: _editorScrollController,
|
|
||||||
controller: _controller,
|
|
||||||
config: QuillEditorConfig(
|
|
||||||
placeholder: 'Start writing your notes...',
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
embedBuilders: [
|
|
||||||
...FlutterQuillEmbeds.editorBuilders(
|
|
||||||
imageEmbedConfig: QuillEditorImageEmbedConfig(
|
|
||||||
imageProviderBuilder: (context, imageUrl) {
|
|
||||||
// https://pub.dev/packages/flutter_quill_extensions#-image-assets
|
|
||||||
if (imageUrl.startsWith('assets/')) {
|
|
||||||
return AssetImage(imageUrl);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
videoEmbedConfig: QuillEditorVideoEmbedConfig(
|
|
||||||
customVideoBuilder: (videoUrl, readOnly) {
|
|
||||||
// To load YouTube videos https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.0
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TimeStampEmbedBuilder(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// child: QuillEditor.basic(
|
|
||||||
// focusNode: _editorFocusNode,
|
|
||||||
// scrollController: _editorScrollController,
|
|
||||||
// controller: _controller,
|
|
||||||
// // readOnly: true,
|
|
||||||
// config: QuillEditorConfig(
|
|
||||||
// requestKeyboardFocusOnCheckListChanged: false,
|
|
||||||
// // readOnlyMouseCursor: SystemMouseCursors.text,
|
|
||||||
// enableScribble: true,
|
|
||||||
// // readOnly: false,
|
|
||||||
// padding: const EdgeInsets.all(8),
|
|
||||||
// placeholder: 'Type something...',
|
|
||||||
// embedBuilders: [
|
|
||||||
// ...FlutterQuillEmbeds.editorBuilders(
|
|
||||||
// imageEmbedConfig: QuillEditorImageEmbedConfig(
|
|
||||||
// imageProviderBuilder: (context, imageUrl) {
|
|
||||||
// // https://pub.dev/packages/flutter_quill_extensions#-image-assets
|
|
||||||
// if (imageUrl.startsWith('assets/')) {
|
|
||||||
// return AssetImage(imageUrl);
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// videoEmbedConfig: QuillEditorVideoEmbedConfig(
|
|
||||||
// customVideoBuilder: (videoUrl, readOnly) {
|
|
||||||
// // To load YouTube videos https://github.com/singerdmx/flutter-quill/releases/tag/v10.8.0
|
|
||||||
// return null;
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// TimeStampEmbedBuilder(),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimeStampEmbed extends Embeddable {
|
|
||||||
const TimeStampEmbed(
|
|
||||||
String value,
|
|
||||||
) : super(timeStampType, value);
|
|
||||||
|
|
||||||
static const String timeStampType = 'timeStamp';
|
|
||||||
|
|
||||||
static TimeStampEmbed fromDocument(Document document) =>
|
|
||||||
TimeStampEmbed(jsonEncode(document.toDelta().toJson()));
|
|
||||||
|
|
||||||
Document get document => Document.fromJson(jsonDecode(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimeStampEmbedBuilder extends EmbedBuilder {
|
|
||||||
@override
|
|
||||||
String get key => 'timeStamp';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toPlainText(Embed node) {
|
|
||||||
return node.value.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(
|
|
||||||
BuildContext context,
|
|
||||||
EmbedContext embedContext,
|
|
||||||
) {
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
const Icon(Icons.access_time_rounded),
|
|
||||||
Text(embedContext.node.value.data as String),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -780,7 +780,8 @@ class _PolicyState extends State<Policy> {
|
|||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(top: 8.0),
|
margin: const EdgeInsets.only(top: 8.0),
|
||||||
// color: Colors.white,
|
// color: Colors.white,
|
||||||
height: isDesktop ? MediaQuery.of(context).size.height * 0.55 : null,
|
height: isDesktop ? 350 : null,
|
||||||
|
// height: isDesktop ? MediaQuery.of(context).size.height * 0.55 : null,
|
||||||
// color: Colors.blueGrey.shade200,
|
// color: Colors.blueGrey.shade200,
|
||||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.15 : null,
|
width: isDesktop ? MediaQuery.of(context).size.width * 0.15 : null,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -966,11 +967,10 @@ class _PolicyState extends State<Policy> {
|
|||||||
child: isDesktop
|
child: isDesktop
|
||||||
? Container(
|
? Container(
|
||||||
// color: Colors.amber,
|
// color: Colors.amber,
|
||||||
child: Expanded(
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [_buildPolicyServiceOrdering(isDesktop)],
|
children: [_buildPolicyServiceOrdering(isDesktop)],
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
@ -995,7 +995,7 @@ class _PolicyState extends State<Policy> {
|
|||||||
List<String> services =
|
List<String> services =
|
||||||
ServicesChoosed!.map((service) => service['name'].toString()).toList();
|
ServicesChoosed!.map((service) => service['name'].toString()).toList();
|
||||||
|
|
||||||
return Expanded(
|
return Container(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Flex(
|
child: Flex(
|
||||||
|
|||||||
14
pubspec.lock
14
pubspec.lock
@ -270,6 +270,11 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.2"
|
version: "0.3.2"
|
||||||
|
flutter_quill:
|
||||||
|
git:
|
||||||
|
url: https://github.com/singerdmx/flutter-quill.git
|
||||||
|
ref: v11.4.1
|
||||||
|
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -283,14 +288,7 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.27"
|
version: "2.0.27"
|
||||||
flutter_quill:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: flutter_quill
|
|
||||||
sha256: "7e60963632bbc8615627f0bae8e178515f69ecb378ad49fa68c43c2aabf33e21"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "11.4.1"
|
|
||||||
flutter_quill_delta_from_html:
|
flutter_quill_delta_from_html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -54,6 +54,7 @@ dependencies:
|
|||||||
flutter_quill_extensions: ^11.0.0
|
flutter_quill_extensions: ^11.0.0
|
||||||
flutter_localization: ^0.3.2
|
flutter_localization: ^0.3.2
|
||||||
reorderables: ^0.6.0
|
reorderables: ^0.6.0
|
||||||
|
html_editor_enhanced: ^1.8.0
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user