works for the first item filtered

This commit is contained in:
Juan Marulanda De Los Rios 2025-06-26 03:57:34 -04:00
parent 5d4bc01a59
commit add5192b3c
7 changed files with 243 additions and 89 deletions

View File

@ -23,10 +23,15 @@ class _SonicEmailViewState extends State<SonicEmailView> {
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<SonicEmailView> {
Column(
children: [
EmailToolbar(
onButtonPressed: () => {},
onJumpToNumbering: _scrollToNumber,
onViewspecs: _handleViewspecs
onButtonPressed: () => {},
onJumpToNumbering: _scrollToNumber,
onViewspecs: _handleViewspecs,
onFiltering: _handleFiltering,
),
Row(
// title of email

View File

@ -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<EmailToolbar> {
),
),
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<void> FilterButton(context) async {
Future<List<AugmentTree>> searchFilter(String query) async {
return [];
}
Future<void> filterButton(context, Function(String) onFilteringCallback) async {
//this is literally ctrl+F :skull:
//idea is to search in file, extract the <p> 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
// }
// }
// }
}

View File

@ -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<CollapsableEmails> {
static bool rightNumbering = true;
bool showWhole = false;
@override
void initState() {
super.initState();
@ -69,6 +70,7 @@ class _CollapsableEmailsState extends State<CollapsableEmails> {
_serializableData(widget.threadIDs); // this
_markdown2Tree(widget.threadMarkdown);
}
@override
void didUpdateWidget(covariant CollapsableEmails oldWidget) {
// TODO: implement didUpdateWidget
@ -294,6 +296,7 @@ class _CollapsableEmailsState extends State<CollapsableEmails> {
},
);
}
void _handleJump(String queryNumbering) {
print(queryNumbering);
if (queryNumbering.isEmpty) {
@ -416,12 +419,11 @@ class _CollapsableEmailsState extends State<CollapsableEmails> {
),
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(),
],

View File

@ -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<CollapsableEmails> createState() => _CollapsableEmailsState();

View File

@ -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<CollapsableEmails> {
int level = 0;
AugmentTree zoomTreeRoot = AugmentTree();
// late AugmentTree currentZoomNode;
late List<AugmentTree> currentZoomTree = [];
late List<AugmentTree> currentZoomTree =
[]; // holds a list of list that holds the list of nodes on the currentzoom
bool zoomOut = false;
bool zoomIn = true;
late List<AugmentTree> threadNodes = [];
static bool leftNumbering = true;
static bool rightNumbering = true;
bool showWhole = false;
List<AugmentTree> queryResults = [];
bool _isFilteringActive = false;
@override
void initState() {
@ -83,6 +88,10 @@ class _CollapsableEmailsState extends State<CollapsableEmails> {
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<CollapsableEmails> {
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<CollapsableEmails> {
}
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<CollapsableEmails> {
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<CollapsableEmails> {
// }
}
void _findNodesContainingStrDFS(
AugmentTree node, String query, List<AugmentTree> results) {
if (node.data.contains(query)) {
results.add(node);
}
for (var child in node.children) {
_findNodesContainingStrDFS(child, query, results);
}
}
List<AugmentTree> _handleFilterQuery(AugmentTree root, String query) {
List<AugmentTree> 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`.

View File

@ -47,6 +47,10 @@ class _EmailViewState extends State<EmailView> {
}
void _filteringQuery(String query){
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -61,7 +65,7 @@ class _EmailViewState extends State<EmailView> {
onButtonPressed: () => {},
onJumpToNumbering: _scrollToNumber,
onViewspecs: _viewSpecs,
onFiltering: _filteringQuery,
),
Row(
children: [

View File

@ -44,6 +44,7 @@ class _EmailViewState extends State<EmailView> {
];
String? _targetJumpNumbering;
String? _targetViewspecs;
String? _queryFiltering;
@override
void initState() {
@ -71,6 +72,12 @@ class _EmailViewState extends State<EmailView> {
});
}
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<EmailView> {
onJumpToNumbering: _handleJumpRequest,
onViewspecs: _handleViewspecsRequest,
onButtonPressed: () => {print("email tool bar pressed")},
onFiltering: _handleFiltering,
),
Row(
// title of email
@ -133,6 +141,7 @@ class _EmailViewState extends State<EmailView> {
threadIDs: widget.id,
targetJumpNumbering: _targetJumpNumbering,
targetViewspecs: _targetViewspecs,
targetFiltering: _queryFiltering,
),
),
],