1 file changed
+98
-1
lib/features/chat/views/components/chat_bubble.dart
+98
-1
@@ -467,7 +467,104 @@ class _ThemedGptMarkdown extends StatelessWidget {
467
468
return GptMarkdownTheme(
469
gptThemeData: gptTheme,
470
- child: GptMarkdown(content, style: style, followLinkColor: true),
470
+ child: GptMarkdown(
471
+ content,
472
+ style: style,
473
+ followLinkColor: true,
474
+ tableBuilder: _buildTable,
475
+ ),
476
+ );
477
+ }
478
+}
479
+
480
+Widget _buildTable(
481
+ BuildContext context,
482
+ List<CustomTableRow> tableRows,
483
+ TextStyle textStyle,
484
+ GptMarkdownConfig config,
485
+) {
486
+ return _TableScrollView(
487
+ tableRows: tableRows,
488
+ config: config,
489
+ );
490
+}
491
+
492
+class _TableScrollView extends StatefulWidget {
493
+ const _TableScrollView({
494
+ required this.tableRows,
495
+ required this.config,
496
+ });
497
+
498
+ final List<CustomTableRow> tableRows;
499
+ final GptMarkdownConfig config;
500
+
501
+ @override
502
+ State<_TableScrollView> createState() => _TableScrollViewState();
503
+}
504
+
505
+class _TableScrollViewState extends State<_TableScrollView> {
506
+ final ScrollController _controller = ScrollController();
507
+
508
+ @override
509
+ void dispose() {
510
+ _controller.dispose();
511
+ super.dispose();
512
+ }
513
+
514
+ @override
515
+ Widget build(BuildContext context) {
516
+ return Scrollbar(
517
+ controller: _controller,
518
+ thumbVisibility: true,
519
+ child: SingleChildScrollView(
520
+ controller: _controller,
521
+ scrollDirection: Axis.horizontal,
522
+ child: Table(
523
+ textDirection: widget.config.textDirection,
524
+ defaultColumnWidth: const IntrinsicColumnWidth(),
525
+ defaultVerticalAlignment: TableCellVerticalAlignment.middle,
526
+ border: TableBorder.all(
527
+ width: 1,
528
+ color: Theme.of(context).colorScheme.onSurface,
529
+ ),
530
+ children: widget.tableRows.map((row) {
531
+ return TableRow(
532
+ decoration: row.isHeader
533
+ ? BoxDecoration(
534
+ color: Theme.of(context).colorScheme.surfaceContainerHighest,
535
+ )
536
+ : null,
537
+ children: row.fields.map((field) {
538
+ Widget content = Padding(
539
+ padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
540
+ child: MdWidget(
541
+ context,
542
+ field.data,
543
+ false,
544
+ config: widget.config,
545
+ ),
546
+ );
547
+ switch (field.alignment) {
548
+ case TextAlign.center:
549
+ content = Center(child: content);
550
+ case TextAlign.right:
551
+ content = Align(
552
+ alignment: Alignment.centerRight,
553
+ child: content,
554
+ );
555
+ case TextAlign.left:
556
+ default:
557
+ content = Align(
558
+ alignment: Alignment.centerLeft,
559
+ child: content,
560
+ );
561
+ }
562
+ return content;
563
+ }).toList(),
564
+ );
565
+ }).toList(),
566
+ ),
567
+ ),
568
);
569
}
570
}