import 'package:flutter/material.dart'; import 'dart:html' as html; import 'dart:js' as js; class EmailToolbar extends StatefulWidget { final Function(String) onJumpToSpan; final VoidCallback onButtonPressed; EmailToolbar( {Key? key, required this.onButtonPressed, required this.onJumpToSpan}) : super(key: key); @override _DynamicClassesAugment createState() => _DynamicClassesAugment(); } class _DynamicClassesAugment extends State { String selectedClass = 'Class 1'; // TextEditingController _jumpController = TextEditingController(); // late final FocusNode _JumpItemfocusNode; // late final FocusNode _viewSpecsfocusNode; // bool _jumpItemHasFocus = false; // bool _viewSpecsHasFocus = false; @override void initState() { super.initState(); // _JumpItemfocusNode = FocusNode(); // _viewSpecsfocusNode = FocusNode(); // _JumpItemfocusNode.addListener(() { // setState(() => _jumpItemHasFocus = _JumpItemfocusNode.hasFocus); // }); // _viewSpecsfocusNode.addListener(() { // setState(() => _viewSpecsHasFocus = _viewSpecsfocusNode.hasFocus); // }); } @override void dispose() { // _JumpItemfocusNode.dispose(); // _viewSpecsfocusNode.dispose(); // _jumpController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { // const animationDuration = Duration(milliseconds: 250); return Column(children: [ Row( children: [ ElevatedButton( onPressed: () => AugmentClasses.handleHome(context), child: Text('Home'), ), SizedBox(width: 8), ElevatedButton( onPressed: AugmentClasses.handleReload, child: Text('Reload'), ), ElevatedButton( onPressed: AugmentClasses.handleImages, child: Text('Images'), ), SizedBox(width: 8), ElevatedButton( onPressed: AugmentClasses.handleOpen, child: Text('Open'), ), // SizedBox(width: 8), ElevatedButton( onPressed: AugmentClasses.handleFind, child: Text('Find'), ), // SizedBox(width: 8), ElevatedButton( onPressed: AugmentClasses.handleStop, child: Text('Stop'), ), Spacer(), PopupMenuButton( onSelected: (String value) { setState(() { selectedClass = value; print(selectedClass); }); }, itemBuilder: (BuildContext context) => >[ const PopupMenuItem( value: 'Class 1', child: Text('Class 1'), ), const PopupMenuItem( value: 'Class 2', child: Text('Class 2'), ), const PopupMenuItem( value: 'Turbo 3', child: Text('Turbo 3'), ), ], // child: ElevatedButton( // onPressed: () {}, child: Text('Options'), ), ], ), if (selectedClass == 'Class 2') Stack(children: [ Row( children: [ ElevatedButton( onPressed: () => AugmentClasses.JumpButton(context), child: Text('JumpItem:'), ), // SizedBox( // width: 8, // ), Container( width: 50, height: 30, child: TextField( // controller: _jumpController, decoration: InputDecoration( border: OutlineInputBorder(), // suffixIcon: Icon(Icons.search) ), onSubmitted: (value) { print("onSubmitted"); if (value.isNotEmpty) { widget.onJumpToSpan(value); } }, ), ), //TODO: Make an animation to make the button a textfield // AnimatedSwitcher( // duration: animationDuration, // transitionBuilder: (Widget child, Animation animation) { // return FadeTransition(opacity: animation, child: child); // }, // child: _jumpItemHasFocus // ? Container( // key: ValueKey('TextField1'), // width: 150, // child: TextField( // focusNode: _JumpItemfocusNode, // decoration: InputDecoration( // hintText: 'Enter Text', // border: OutlineInputBorder(), // ), // ), // ) // : Container( // key: ValueKey('Button1'), // child: ElevatedButton( // onPressed: () => _JumpItemfocusNode.requestFocus(), // child: Text('Jump Item:'), // ), // ), // ), SizedBox(width: 8), ElevatedButton( onPressed: () => AugmentClasses.ViewSpecsButton(context), child: Text('ViewSpecs:')), Container( width: 50, height: 30, child: TextField( decoration: InputDecoration( labelText: '', border: OutlineInputBorder(), // suffixIcon: Icon(Icons.style_rounded) ), ), ), ElevatedButton( onPressed: () => AugmentClasses.FilterButton(context), child: Text('Filter'), ), SizedBox(width: 8), ElevatedButton( onPressed: AugmentClasses.handleOpen, child: Text('Lookup'), ), // SizedBox(width: 8), ElevatedButton( onPressed: AugmentClasses.handleFind, child: Text('Create Link'), ), ElevatedButton( onPressed: AugmentClasses.handleFind, child: Text('Paste Link'), ), ], ) ]) ]); } } class AugmentClasses { static void handleHome(BuildContext context) { Navigator.of(context).popUntil((route) => route.isFirst); } static void handleReload() { print("reload"); } static void handleImages() { print("Images button pressed"); } static void handleOpen() { print("Open button pressed"); } static void handleFind() { print("Find button pressed"); } static void handleStop() { print("Stop button pressed"); } static void handleJump(String spanId) { String js_code = ''' var iframe = document.getElementsByTagName('iframe')[0]; // 0 for the first iframe, 1 for the second, etc. // Check if the iframe is loaded and has content if (iframe && iframe.contentDocument) { // Access the document inside the iframe var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; // Find the element with the specific id inside the iframe var targetElement = iframeDoc.getElementById("$spanId"); // Replace '36 ' with the actual id of the target element // If the element exists, scroll to it if (targetElement) { targetElement.scrollIntoView(); console.log('Scrolled to element with id "$spanId" inside the iframe.'); } else { console.log('Element with id "$spanId" not found inside the iframe.'); } } else { console.log('Iframe not found or not loaded.'); } '''; js.context.callMethod('eval', [js_code]); } static void invisibility(String htmlClass) {} static Future JumpButton(BuildContext context) async { // FocusNode textFieldFocusNode = FocusNode(); AugmentClasses.disableIframePointerEvents(); await showDialog( barrierDismissible: true, // barrierColor: Colors.yellow, context: context, builder: (context) => AlertDialog( title: Text('Jump Item:'), content: Container( width: 300, height: 170, child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Jump (to) Item (at)'), SizedBox(height: 10), TextField( autofocus: true, decoration: InputDecoration( labelText: '...', border: OutlineInputBorder(), suffixIcon: Icon(Icons.search)), onSubmitted: (value) { print("onSubmitted: $value"); if (value.isNotEmpty) { handleJump(value); Navigator.of(context).pop(); } }, ), Spacer( flex: 5, ), Row( mainAxisSize: MainAxisSize.min, children: [ ElevatedButton( onPressed: () => AugmentClasses.ViewSpecsButton(context), child: Text("Viewspecs:"), ), SizedBox( width: 150, child: TextField( maxLines: 1, decoration: InputDecoration( labelText: '', border: OutlineInputBorder(), suffixIcon: Icon(Icons.search)), onSubmitted: (value) { print("onSubmitted: $value"); if (value.isNotEmpty) { handleJump(value); Navigator.of(context).pop(); } }, ), ), ], ), ], ), ), actions: [ ElevatedButton( onPressed: () { //TODO: Grab both textfields and call both of the functions handles }, child: Text('OK')), TextButton( onPressed: () { Navigator.of(context).pop(); // print('close pressed'); }, child: Text('Cancel'), ), ElevatedButton( onPressed: () { //TODO: in the ui demo didn't see it }, child: Text('Help')) ], ), ).then((_) { AugmentClasses.enableIframePointerEvents(); }); } static Future ViewSpecsButton(context) async { //TODO: finish it bool blankLines = false; bool numbering = false; bool statementSignatures = false; AugmentClasses.disableIframePointerEvents(); await showDialog( context: context, builder: (context) => Container( height: 150, width: 300, child: AlertDialog( title: Text('Viewspecs(short)'), content: Container( width: 400, // Set the width to simulate the Windows style child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ // First section: Checkboxes for "Show" Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Show'), Row( children: [ Text("y z"), Checkbox( value: blankLines, onChanged: (bool? value) { blankLines = value!; }, ), Text('Blank lines'), ], ), Row( children: [ Text('m n'), Checkbox( value: numbering, onChanged: (bool? value) { numbering = value!; }, ), Text('Numbering'), ], ), Row( children: [ Text('K L'), Checkbox( value: statementSignatures, onChanged: (bool? value) { statementSignatures = value!; }, ), Text('Statement signatures'), ], ), ], ), ), // Second section: Numeric input for Outline, Levels, and Lines Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Outline'), Row( children: [ Text('Levels'), SizedBox(width: 10), Container( width: 40, child: TextField( decoration: InputDecoration( isDense: true, border: OutlineInputBorder(), ), keyboardType: TextInputType.number, ), ), ], ), Row( children: [ Text('Lines'), SizedBox(width: 10), Container( width: 40, child: TextField( decoration: InputDecoration( isDense: true, border: OutlineInputBorder(), ), keyboardType: TextInputType.number, ), ), ], ), ], ), ), ], ), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ElevatedButton(onPressed: () {}, child: Text('OK')), ElevatedButton( onPressed: () { AugmentClasses.disableIframePointerEvents(); Navigator.of(context).pop(); }, child: Text('Cancel')), ElevatedButton( onPressed: () {}, child: Text('Reset')), ElevatedButton(onPressed: () {}, child: Text('Help')), ], ), ], ), ), ), )).then((_) { AugmentClasses.enableIframePointerEvents(); // may be useless? }); } void handleFilter() {} static Future FilterButton(context) async { //this is literally ctrl+F :skull: //idea is to search in file, extract the

tags that contain these //words and highlight, then when zoom, you just jump to that paragraph AugmentClasses.disableIframePointerEvents(); await showDialog( context: context, builder: (context) => Container( height: 150, width: 300, child: AlertDialog( title: Text('Filter'), content: Container( width: 400, // Set the width to simulate the Windows style child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Set filter:'), SizedBox( width: 175, child: TextField( maxLines: 1, decoration: InputDecoration( border: OutlineInputBorder(), ), ), ) ], ))))); } static void disableIframePointerEvents() { final iframes = html.document.getElementsByTagName('iframe'); for (var iframe in iframes) { if (iframe is html.Element) { iframe.style.pointerEvents = 'none'; // Disable pointer events } } } static void enableIframePointerEvents() { final iframes = html.document.getElementsByTagName('iframe'); for (var iframe in iframes) { if (iframe is html.Element) { iframe.style.pointerEvents = 'auto'; // Re-enable pointer events } } } }