madari-oss/lib/features/collection/container/collection_markdown_renderer.dart
Madari Developers 16fe4a653f Project import generated by Copybara.
GitOrigin-RevId: 829626e92d5dba6a4586d1e7c4bd1615ec396e88
2025-01-02 18:46:26 +00:00

155 lines
4.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
class MarkdownRenderer extends StatelessWidget {
final String content;
final int previewLines;
const MarkdownRenderer({
super.key,
required this.content,
this.previewLines = 3,
});
@override
Widget build(BuildContext context) {
final String previewText =
content.split('\n').take(previewLines).join('\n');
final bool hasMore = content.split('\n').length > previewLines;
return InkWell(
onTap: () => _showFullMarkdown(context),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MarkdownBody(
data: previewText,
shrinkWrap: true,
styleSheet: MarkdownStyleSheet(
p: Theme.of(context).textTheme.bodyMedium,
h1: Theme.of(context).textTheme.headlineSmall,
h2: Theme.of(context).textTheme.titleLarge,
),
),
if (hasMore) ...[
const SizedBox(height: 8),
Text(
'Tap to read more...',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.primary,
),
),
],
],
),
),
);
}
void _showFullMarkdown(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => FullMarkdownSheet(content: content),
);
}
}
class FullMarkdownSheet extends StatelessWidget {
final String content;
const FullMarkdownSheet({
super.key,
required this.content,
});
@override
Widget build(BuildContext context) {
return DraggableScrollableSheet(
initialChildSize: 0.9,
minChildSize: 0.5,
maxChildSize: 0.95,
builder: (context, scrollController) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(16),
),
),
child: Column(
children: [
// Handle bar
Container(
margin: const EdgeInsets.symmetric(vertical: 8),
width: 40,
height: 4,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(2),
),
),
// Actions bar
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: const Icon(Icons.close),
onPressed: () => Navigator.pop(context),
),
Row(
children: [
IconButton(
icon: const Icon(Icons.copy),
onPressed: () {
// Copy to clipboard
// You might want to add feedback when copied
},
),
IconButton(
icon: const Icon(Icons.share),
onPressed: () {
// Implement share functionality
},
),
],
),
],
),
),
// Markdown content
Expanded(
child: Markdown(
controller: scrollController,
data: content,
styleSheet: MarkdownStyleSheet(
p: Theme.of(context).textTheme.bodyLarge,
h1: Theme.of(context).textTheme.headlineMedium,
h2: Theme.of(context).textTheme.headlineSmall,
h3: Theme.of(context).textTheme.titleLarge,
code: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontFamily: 'monospace',
backgroundColor: Colors.grey[200],
),
codeblockDecoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(8),
),
),
selectable: true,
padding: const EdgeInsets.all(16),
),
),
],
),
);
},
);
}
}