From add5192b3cde14fb8a9281e6e67413566bb08a33 Mon Sep 17 00:00:00 2001 From: juan Date: Thu, 26 Jun 2025 03:57:34 -0400 Subject: [PATCH] works for the first item filtered --- lib/SonicEmailViewWeb.dart | 12 ++- lib/augment.dart | 145 ++++++++++++++++++------------ lib/collapsableEmailsAndroid.dart | 28 +++--- lib/collapsableEmailsStub.dart | 2 +- lib/collapsableEmailsWeb.dart | 130 +++++++++++++++++++++++---- lib/emailViewAndroid.dart | 6 +- lib/emailViewWeb.dart | 9 ++ 7 files changed, 243 insertions(+), 89 deletions(-) diff --git a/lib/SonicEmailViewWeb.dart b/lib/SonicEmailViewWeb.dart index b5b127a..c1d6881 100644 --- a/lib/SonicEmailViewWeb.dart +++ b/lib/SonicEmailViewWeb.dart @@ -23,10 +23,15 @@ class _SonicEmailViewState extends State { void _scrollToNumber(String spanId) { AugmentClasses.handleJump(spanId); } + void _handleViewspecs(String queryViewspecs) { return; } + void _handleFiltering(String query) { + return; + } + @override void initState() { super.initState(); @@ -92,9 +97,10 @@ class _SonicEmailViewState extends State { Column( children: [ EmailToolbar( - onButtonPressed: () => {}, - onJumpToNumbering: _scrollToNumber, - onViewspecs: _handleViewspecs + onButtonPressed: () => {}, + onJumpToNumbering: _scrollToNumber, + onViewspecs: _handleViewspecs, + onFiltering: _handleFiltering, ), Row( // title of email diff --git a/lib/augment.dart b/lib/augment.dart index 8b8fa60..4be4e23 100644 --- a/lib/augment.dart +++ b/lib/augment.dart @@ -9,10 +9,15 @@ class EmailToolbar extends StatefulWidget { final Function(String) onJumpToNumbering; final Function(String) onViewspecs; final VoidCallback onButtonPressed; + final Function(String) onFiltering; - EmailToolbar( - {Key? key, required this.onButtonPressed, required this.onJumpToNumbering, required this.onViewspecs}) - : super(key: key); + EmailToolbar({ + Key? key, + required this.onButtonPressed, + required this.onJumpToNumbering, + required this.onViewspecs, + required this.onFiltering, + }) : super(key: key); @override _DynamicClassesAugment createState() => _DynamicClassesAugment(); @@ -196,7 +201,7 @@ class _DynamicClassesAugment extends State { ), ), ElevatedButton( - onPressed: () => AugmentClasses.FilterButton(context), + onPressed: () => AugmentClasses().filterButton(context, widget.onFiltering), child: Text('Filter'), ), SizedBox(width: 8), @@ -702,7 +707,6 @@ class AugmentClasses { ElevatedButton(onPressed: () {}, child: Text('OK')), ElevatedButton( onPressed: () { - // AugmentClasses.disableIframePointerEvents(); Navigator.of(context).pop(); }, child: Text('Cancel')), @@ -720,61 +724,92 @@ class AugmentClasses { }); } - void handleFilter() {} - static Future FilterButton(context) async { + Future> searchFilter(String query) async { + return []; + } + + Future filterButton(context, Function(String) onFilteringCallback) 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 + bool? numbering = false; + String filterQueue = ''; - // 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(), - ), + context: context, + builder: (BuildContext dialogContext) { + // => Container( + // height: 150, + // width: 300, + // child: + return StatefulBuilder(builder: + (BuildContext statefulBuilderContext, StateSetter setState) { + return AlertDialog( + title: const Text('Filter'), + content: SizedBox( + width: 400, // Set the width to simulate the Windows style + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Set filter:'), + SizedBox( + width: 175, + child: TextField( + maxLines: 1, + decoration: const InputDecoration( + border: OutlineInputBorder(), ), - ) - ], - ))))); + onChanged: (value) { + print(value); + filterQueue = value; + }, + ), + ), + SizedBox( + height: 10, + ), + Column(children: [ + Row(children: [ + Checkbox( + value: numbering, + activeColor: + Theme.of(context).colorScheme.tertiary, + onChanged: (newBool) { + setState(() { + numbering = newBool; + }); + }), + Text("Start at top of file") + ]), + ]), + ])), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text("Cancel")), + ElevatedButton( + onPressed: () { + Navigator.of(context).pop({ + 'filterQueue': filterQueue, + 'numbering': numbering, + }); + }, + child: Text("Apply")), + ], + ); + }); + }, + ).then((result) { + if (result != null) { + print("filter done $result"); + final String query = result['filterQueue']; + onFilteringCallback(query); + } else { + print('cancelled'); + } + }); } - - // static void disableIframePointerEvents() { - // //pretty sure these dont work - // // final iframes = html.document.getElementsByTagName('iframe'); - // final iframes = web.document.getElementsByTagName('iframe'); - // for (var iframe in iframes) { - // // if (iframe is html.Element) { - // // iframe.style.pointerEvents = 'none'; // Disable pointer events - // if (iframe is web.Element) { - // iframe. - // } - // } - // } - - // static void enableIframePointerEvents() { - // // final iframes = html.document.getElementsByTagName('iframe'); - // final iframes = html.document.getElementsByTagName('iframe'); - - // for (var iframe in iframes) { - // if (iframe is html.Element) { - // iframe.style.pointerEvents = 'auto'; // Re-enable pointer events - // } - // } - // } } diff --git a/lib/collapsableEmailsAndroid.dart b/lib/collapsableEmailsAndroid.dart index d89afb4..ae432e8 100644 --- a/lib/collapsableEmailsAndroid.dart +++ b/lib/collapsableEmailsAndroid.dart @@ -12,13 +12,15 @@ class CollapsableEmails extends StatefulWidget { final String threadIDs; final String? targetJumpNumbering; final String? targetViewspecs; + final String? targetFiltering; - CollapsableEmails( - {required this.thread, - required this.threadMarkdown, - required this.threadIDs, - this.targetJumpNumbering, - this.targetViewspecs, + CollapsableEmails({ + required this.thread, + required this.threadMarkdown, + required this.threadIDs, + this.targetJumpNumbering, + this.targetViewspecs, + this.targetFiltering, }); @override @@ -59,7 +61,6 @@ class _CollapsableEmailsState extends State { static bool rightNumbering = true; bool showWhole = false; - @override void initState() { super.initState(); @@ -69,6 +70,7 @@ class _CollapsableEmailsState extends State { _serializableData(widget.threadIDs); // this _markdown2Tree(widget.threadMarkdown); } + @override void didUpdateWidget(covariant CollapsableEmails oldWidget) { // TODO: implement didUpdateWidget @@ -294,6 +296,7 @@ class _CollapsableEmailsState extends State { }, ); } + void _handleJump(String queryNumbering) { print(queryNumbering); if (queryNumbering.isEmpty) { @@ -416,12 +419,11 @@ class _CollapsableEmailsState extends State { ), if (isExpanded) ConstrainedBox( - constraints: BoxConstraints( - minHeight: 100, - maxHeight: - MediaQuery.of(context).size.height * 0.6, - ), - child: _buildForZooms(index), + constraints: BoxConstraints( + minHeight: 100, + maxHeight: MediaQuery.of(context).size.height * 0.6, + ), + child: _buildForZooms(index), ), Divider(), ], diff --git a/lib/collapsableEmailsStub.dart b/lib/collapsableEmailsStub.dart index dd9168f..b523f71 100644 --- a/lib/collapsableEmailsStub.dart +++ b/lib/collapsableEmailsStub.dart @@ -9,7 +9,7 @@ class CollapsableEmails extends StatefulWidget { CollapsableEmails( {required this.thread, required this.threadMarkdown, - required this.threadIDs, String? targetJumpNumbering, String? targetViewspecs}); + required this.threadIDs, String? targetJumpNumbering, String? targetViewspecs, String? targetFiltering}); @override State createState() => _CollapsableEmailsState(); diff --git a/lib/collapsableEmailsWeb.dart b/lib/collapsableEmailsWeb.dart index 1183259..dfb1309 100644 --- a/lib/collapsableEmailsWeb.dart +++ b/lib/collapsableEmailsWeb.dart @@ -13,6 +13,7 @@ class CollapsableEmails extends StatefulWidget { final String threadIDs; final String? targetJumpNumbering; final String? targetViewspecs; + final String? targetFiltering; const CollapsableEmails({ required this.thread, @@ -21,6 +22,7 @@ class CollapsableEmails extends StatefulWidget { required this.threadIDs, this.targetJumpNumbering, this.targetViewspecs, + this.targetFiltering, }); @override @@ -53,13 +55,16 @@ class _CollapsableEmailsState extends State { int level = 0; AugmentTree zoomTreeRoot = AugmentTree(); // late AugmentTree currentZoomNode; - late List currentZoomTree = []; + late List currentZoomTree = + []; // holds a list of list that holds the list of nodes on the currentzoom bool zoomOut = false; bool zoomIn = true; late List threadNodes = []; static bool leftNumbering = true; static bool rightNumbering = true; bool showWhole = false; + List queryResults = []; + bool _isFilteringActive = false; @override void initState() { @@ -83,6 +88,10 @@ class _CollapsableEmailsState extends State { widget.targetViewspecs != oldWidget.targetViewspecs) { _handleViewspecs(widget.targetViewspecs!); } + if (widget.targetFiltering != null && + widget.targetFiltering != oldWidget.targetFiltering) { + _handleFilterQuery(zoomTreeRoot, widget.targetFiltering!); + } } @override @@ -90,17 +99,6 @@ class _CollapsableEmailsState extends State { super.dispose(); } - // void _markdownConverter() async { - // // to list of markdown - // // for (int email = 0; email < widget.threadHTML.length; email++) { - // // String markdown = html2md.convert(widget.threadHTML[email]); - // // allMarkdown.add(markdown); - // // } - // for (int email = 0; email < widget.threadMarkdown.length; email++) { - // allMarkdown.add(email); - // } - // } - void _add2Tree(AugmentTree tree, md.Element node2add) { // adds node to its corresponding place AugmentTree newNode = AugmentTree(); @@ -228,15 +226,89 @@ class _CollapsableEmailsState extends State { } Widget _buildForZooms(int indexThread) { - // IF I GIVE IT THE INDEX???? if (!_isLoaded) { return const Center(child: CircularProgressIndicator()); // loading screen } - final AugmentTree currentZoomNodeForThisEmail = + final AugmentTree + currentZoomNodeForThisEmail = //each index is an email in the thread currentZoomTree[indexThread]; + print(currentZoomNodeForThisEmail.data); + print(currentZoomNodeForThisEmail.children); + print(currentZoomNodeForThisEmail.parent); + final canZoomOut = currentZoomNodeForThisEmail.parent != null; + if (currentZoomNodeForThisEmail.children.isEmpty) { + return ListView.builder( + itemCount: 1, + itemBuilder: (context, index) { + final childNode = currentZoomNodeForThisEmail; + // final childNode = currentZoomNodeForThisEmail.children[index]; + final canZoomIn = childNode.children.isNotEmpty; + // currentZoomNodeForThisEmail.addNumbering(); + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0), + child: Material( + elevation: 1, + borderRadius: BorderRadius.circular(12), + color: Theme.of(context).colorScheme.surface, + surfaceTintColor: Theme.of(context).colorScheme.surfaceBright, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Wrap( + spacing: 4.0, + children: [ + OutlinedButton( + onPressed: + canZoomOut ? () => _goToParent(indexThread) : null, + child: Icon(Icons.north_west_sharp), + ), + OutlinedButton( + onPressed: canZoomIn + ? () => _goToChildren(indexThread, index) + : null, + child: Icon(Icons.south_east_sharp), + ), + ], + ), + SizedBox(width: 12.0), + if (leftNumbering) + Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 5, 0), + child: Text( + childNode.numbering, + style: + TextStyle(color: Color(Colors.purple[400]!.value)), + ), + ), + Expanded( + child: MarkdownBlock( + data: childNode.data, + config: MarkdownConfig + .darkConfig, // or lightConfig depending on theme + ), + ), + if (rightNumbering) + Padding( + padding: const EdgeInsets.fromLTRB(5, 10, 5, 0), + child: Text( + childNode.numbering, + style: + TextStyle(color: Color(Colors.purple[400]!.value)), + ), + ), + ], + ), + ), + ), + ); + }, + ); + } return ListView.builder( itemCount: currentZoomNodeForThisEmail.children.length, @@ -285,8 +357,6 @@ class _CollapsableEmailsState extends State { Expanded( child: MarkdownBlock( data: childNode.data, - // data: currentZoomNode - // .children[index].data, // one string of markdown config: MarkdownConfig .darkConfig, // or lightConfig depending on theme ), @@ -389,6 +459,34 @@ class _CollapsableEmailsState extends State { // } } + void _findNodesContainingStrDFS( + AugmentTree node, String query, List results) { + if (node.data.contains(query)) { + results.add(node); + } + for (var child in node.children) { + _findNodesContainingStrDFS(child, query, results); + } + } + + List _handleFilterQuery(AugmentTree root, String query) { + List results = []; + final int targetEmailIndex = _expandedEmails.first; + _findNodesContainingStrDFS(root, query, results); + print(results); + for (var res in results) { + print(res.data); + } + if (results.isNotEmpty) { + setState(() { + currentZoomTree[targetEmailIndex] = results.first; // Update the state + _isFilteringActive = true; + }); + print(currentZoomTree); + } + return results; + } + AugmentTree? _findNodeByNumbering(AugmentTree root, String numbering) { //recursively finds the node you mentioned // to find the AugmentTree node corresponding to the `numbering`. diff --git a/lib/emailViewAndroid.dart b/lib/emailViewAndroid.dart index 7b257a2..9f81432 100644 --- a/lib/emailViewAndroid.dart +++ b/lib/emailViewAndroid.dart @@ -47,6 +47,10 @@ class _EmailViewState extends State { } + void _filteringQuery(String query){ + + } + @override Widget build(BuildContext context) { return Scaffold( @@ -61,7 +65,7 @@ class _EmailViewState extends State { onButtonPressed: () => {}, onJumpToNumbering: _scrollToNumber, onViewspecs: _viewSpecs, - + onFiltering: _filteringQuery, ), Row( children: [ diff --git a/lib/emailViewWeb.dart b/lib/emailViewWeb.dart index ceb4ef1..ae7f624 100644 --- a/lib/emailViewWeb.dart +++ b/lib/emailViewWeb.dart @@ -44,6 +44,7 @@ class _EmailViewState extends State { ]; String? _targetJumpNumbering; String? _targetViewspecs; + String? _queryFiltering; @override void initState() { @@ -71,6 +72,12 @@ class _EmailViewState extends State { }); } + void _handleFiltering(String query) { + setState(() { + _queryFiltering = query; + }); + } + // TODO: void _invisibility(String ) //to make purple numbers not visible @override @@ -88,6 +95,7 @@ class _EmailViewState extends State { onJumpToNumbering: _handleJumpRequest, onViewspecs: _handleViewspecsRequest, onButtonPressed: () => {print("email tool bar pressed")}, + onFiltering: _handleFiltering, ), Row( // title of email @@ -133,6 +141,7 @@ class _EmailViewState extends State { threadIDs: widget.id, targetJumpNumbering: _targetJumpNumbering, targetViewspecs: _targetViewspecs, + targetFiltering: _queryFiltering, ), ), ],