import 'package:crab_ui/api_service.dart'; import 'package:crab_ui/structs.dart'; import 'package:flutter/material.dart'; import 'package:super_editor/super_editor.dart'; import 'package:super_editor_markdown/super_editor_markdown.dart'; class ComposeEmail extends StatefulWidget { final VoidCallback onClose; final Function(String) onMinimize; final Function(String) onSendMessage; GetThreadResponse? emailDraftID; ComposeEmail( {Key? key, required this.onMinimize, required this.onClose, required this.onSendMessage, this.emailDraftID}) : super(key: key); @override _ComposeEmailState createState() => _ComposeEmailState(); } class _ComposeEmailState extends State { // if one were to alter a mutableDocument, one should only alter the document through EditRequest to the Editor late final Editor _editor; late final MutableDocument _document; late final MutableDocumentComposer _composer; TextEditingController _emailRecipientController = TextEditingController(); TextEditingController _emailSubjectController = TextEditingController(); List? contentOfDraft; bool isInitialized = false; @override void initState() { super.initState(); _loadDraftContent(); } void _loadDraftContent() async { if (widget.emailDraftID != null) { String? drafted = widget.emailDraftID?.messages.last; if (drafted != null) { contentOfDraft = await ApiService().fetchMarkdownContent([drafted!], "Drafts"); setState(() { _document = MutableDocument(nodes: [ ParagraphNode( id: Editor.createNodeId(), text: AttributedText(contentOfDraft?[0] ?? ""), // NOW THIS SHOULD BE WTV ITS IN DRAFTS ) ]); _composer = MutableDocumentComposer(); _editor = createDefaultDocumentEditor( document: _document, composer: _composer); _emailRecipientController.text = widget.emailDraftID!.to[0].address; _emailSubjectController.text = widget.emailDraftID!.subject; isInitialized = true; }); } } else { setState(() { _document = MutableDocument(nodes: [ ParagraphNode( id: Editor.createNodeId(), text: AttributedText(""), ), ]); _composer = MutableDocumentComposer(); _editor = createDefaultDocumentEditor( document: _document, composer: _composer); isInitialized = true; }); } } @override void dispose() { _editor.dispose(); _emailRecipientController.dispose(); _emailSubjectController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { if (!isInitialized) { return Center( child: CircularProgressIndicator(), ); } return Positioned( bottom: 10.0, right: 10.0, child: Material( elevation: 8.0, child: Container( width: 600.0, height: 616.0, decoration: BoxDecoration( color: Colors.white, ), child: Column(children: [ AppBar( title: const Text("new message"), actions: [ IconButton( onPressed: () { //TODO: implement minimize, and submit email to drafts widget.onClose(); }, icon: Icon(Icons.minimize, color: Colors.grey[600])), IconButton( onPressed: () { //TODO: implement maximizing the window or widget }, icon: Icon(Icons.maximize, color: Colors.grey[600])), IconButton( onPressed: () { widget.onClose(); }, icon: Icon(Icons.close, color: Colors.grey[600])), ], ), Container( // TODO: WHEN NOT CLICKED ITS ONLY A TEXTFIELD WITH A HINT, AND THEN WHEN CLICKED THIS // width: 500.0, // height: 40.0, child: Row( children: [ TextButton(onPressed: () {}, child: Text("To:")), Expanded( child: TextField( controller: _emailRecipientController, ), ), TextButton(onPressed: () {}, child: Text("Cc")), SizedBox( width: 4.0, ), TextButton(onPressed: () {}, child: Text("Bcc")), ], ), ), SizedBox( height: 4, ), Container( // TODO: WHEN NOT CLICKED ITS ONLY A TEXTFIELD WITH A HINT, AND THEN WHEN CLICKED THIS width: 500.0, // height: 40.0, child: Row( children: [ Expanded( child: TextField( controller: _emailSubjectController, decoration: InputDecoration( hintText: "Subject", ), ), ) ], ), ), Expanded( //here the widget goes child: SuperEditor( //make this its own editor: _editor, plugins: {MarkdownInlineUpstreamSyntaxPlugin()}, // stylesheet: Stylesheet( // rules: [StyleRule(BlockSelector.all, (doc, docNode) { // return { // Styles.maxWidth: 640.0, // Styles.padding: const CascadingPadding.symmetric(horizontal: 24), // Styles.textStyle: const TextStyle( // color: Colors.black, // // fontSize: 15, // height: 1.4, // ), // }; // }),], // inlineTextStyler: defaultInlineTextStyler) ), ), Container( padding: EdgeInsets.symmetric(horizontal: 20, vertical: 5), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ ElevatedButton( onPressed: () { print('sent'); String markdown = serializeDocumentToMarkdown(_editor.document); print(_emailRecipientController.text); print(_emailSubjectController.text); print(markdown); ApiService().sendEmail(_emailRecipientController.text, _emailSubjectController.text, markdown); }, style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30)), elevation: 4, foregroundColor: Colors.white, backgroundColor: Colors.blueAccent), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Text( 'Send', style: TextStyle(fontWeight: FontWeight.bold), ), // const SizedBox( // width: 8, // ), // Container( // height: 30, width: 1.0, color: Colors.white), // const SizedBox( // width: 8, // ), // const Icon( // Icons.arrow_drop_down, // size: 24, // ) ], ), ), ], ), ) ])), ), ); } } class OverlayService { static final OverlayService _instance = OverlayService._internal(); factory OverlayService() => _instance; OverlayService._internal(); OverlayEntry? _overlayEntry; GetThreadResponse? draftID; void showPersistentWidget(BuildContext context) { if (_overlayEntry != null) { print("overlay visible"); return; } _overlayEntry = OverlayEntry( builder: (context) => ComposeEmail( onClose: () { removeComposeWidget(); }, onMinimize: (String content) { minimizeComposeWidget(content); }, onSendMessage: (message) { print('msg senf form overlay $message'); }, emailDraftID: draftID)); Navigator.of(context).overlay?.insert(_overlayEntry!); print("inserted into tree"); } void removeComposeWidget() { _overlayEntry?.remove(); _overlayEntry = null; } String minimizeComposeWidget(String content) { //just hide the overlay but keep its info return ''; } }