Files
trombon_ip_browser/lib/views/doc_viewer.dart
2026-05-10 02:54:27 +03:00

92 lines
2.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_markdown/flutter_markdown.dart';
class DocViewer extends StatefulWidget {
const DocViewer({
super.key,
required this.title,
required this.imagePath,
required this.docPath,
});
final String title;
final String imagePath;
final String docPath;
@override
State<DocViewer> createState() => _DocViewerState();
}
class _DocViewerState extends State<DocViewer> {
String _markdownContent = '';
bool _isLoading = true;
String? _error;
@override
void initState() {
super.initState();
_loadMarkdown();
}
Future<void> _loadMarkdown() async {
try {
final content = await rootBundle.loadString(widget.docPath);
setState(() {
_markdownContent = content;
_isLoading = false;
});
} catch (e) {
setState(() {
_error = e.toString();
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: _error != null
? Center(child: Text('Ошибка загрузки: $_error'))
: ListView(
padding: const EdgeInsets.all(16),
children: [
ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.asset(
widget.imagePath,
fit: BoxFit.contain,
width: double.infinity,
height: 220,
),
),
const SizedBox(height: 24),
MarkdownBody(
data: _markdownContent,
styleSheet: MarkdownStyleSheet(
h1: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
h2: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.primary,
),
p: const TextStyle(fontSize: 15, height: 1.5),
listBullet: const TextStyle(fontSize: 15),
),
),
const SizedBox(height: 32),
],
),
);
}
}